Network Working GroupF. Strauss
Internet-DraftTU Braunschweig
Expires: August 15, 2000February 15, 2000
 TOC 

SMIng - A new Structure of Management Information draft-irtf-nmrg-sming-02

Status of this Memo

This document is an Internet-Draft and is in full conformance with all provisions of Section 10 of RFC2026.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet-Drafts.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

To view the entire list of Internet-Drafts Shadow Directories, see http://www.ietf.org/shadow.html.

This Internet-Draft will expire on August 15, 2000.

Abstract

This memo presents a language for management information specifications. It eliminates known problems present in the current SMIv2 as specified in [2], [3], and [4]. Language extensibility features and a more efficient and programmer-friendly notation are introduced. Conversions from SMIv2 to SMIng and vice versa are also considered by this document.

Copyright Notice

Copyright (C) The Internet Society (2000). All Rights Reserved.



 TOC 

Table of Contents

1. Introduction
1.1 Terminology
1.2 Relation to SNMP
2. The Information Model
2.1 Identifiers
2.2 Object Identifier Hierarchy
2.3 Kinds of Nodes
2.4 Scalar and Columnar Objects' Instances
3. Base Types and Derived Types
3.1 OctetString
3.2 ObjectIdentifier
3.3 Integer32
3.4 Integer64
3.5 Unsigned32
3.6 Unsigned64
3.7 Float32
3.8 Float64
3.9 Float128
3.10 Enumeration
3.11 Bits
3.12 Display Formats
4. The SMIng File Structure
4.1 Comments
4.2 Statements and Arguments
5. The module Statement
5.1 The module's import Statement
5.2 The module's organization Statement
5.3 The module's contact Statement
5.4 The module's description Statement
5.5 The module's reference Statement
5.6 The module's revision Statement
5.6.1 The revision's date Statement
5.6.2 The revision's description Statement
5.7 The module's identity Statement
5.8 Usage Example
6. The extension Statement
6.1 The extension's status Statement
6.2 The extension's description Statement
6.3 The extension's reference Statement
6.4 The extension's abnf Statement
7. The typedef Statement
7.1 The typedef's type Statement
7.2 The typedef's default Statement
7.3 The typedef's format Statement
7.4 The typedef's units Statement
7.5 The typedef's status Statement
7.6 The typedef's description Statement
7.7 The typedef's reference Statement
7.8 Usage Examples
8. The node Statement
8.1 The node's oid Statement
8.2 The node's status Statement
8.3 The node's description Statement
8.4 The node's reference Statement
8.5 Usage Examples
9. The scalar Statement
9.1 The scalar's oid Statement
9.2 The scalar's type Statement
9.3 The scalar's access Statement
9.4 The scalar's default Statement
9.5 The scalar's format Statement
9.6 The scalar's units Statement
9.7 The scalar's status Statement
9.8 The scalar's description Statement
9.9 The scalar's reference Statement
9.10 Usage Examples
10. The table Statement
10.1 The table's oid Statement
10.2 The table's status Statement
10.3 The table's description Statement
10.4 The table's reference Statement
10.5 The table's row Statement
10.5.1 The row's oid Statement
10.5.2 Table Indexing Statements
10.5.2.1 The row's index Statement for Table Indexing
10.5.2.2 The row's augments Statement for Table Indexing
10.5.2.3 The row's sparse Statement for Table Indexing
10.5.2.4 The row's reorders Statement for Table Indexing
10.5.2.5 The row's expands Statement for Table Indexing
10.5.3 The row's create Statement
10.5.4 The row's status Statement
10.5.5 The row's description Statement
10.5.6 The row's reference Statement
10.6 The table row's column Statement
10.6.1 The column's oid Statement
10.6.2 The column's type Statement
10.6.3 The column's access Statement
10.6.4 The column's default Statement
10.6.5 The column's format Statement
10.6.6 The column's units Statement
10.6.7 The column's status Statement
10.6.8 The column's description Statement
10.6.9 The column's reference Statement
10.7 Usage Example
11. The notification Statement
11.1 The notification's oid Statement
11.2 The notification's objects Statement
11.3 The notification's status Statement
11.4 The notification's description Statement
11.5 The notification's reference Statement
11.6 Usage Example
12. The group Statement
12.1 The group's oid Statement
12.2 The group's members Statement
12.3 The group's status Statement
12.4 The group's description Statement
12.5 The group's reference Statement
12.6 Usage Example
13. The compliance Statement
13.1 The compliance's oid Statement
13.2 The compliance's status Statement
13.3 The compliance's description Statement
13.4 The compliance's reference Statement
13.5 The compliance's mandatory Statement
13.6 The compliance's optional Statement
13.6.1 The optional's description Statement
13.7 The compliance's refine Statement
13.7.1 The refine's type Statement
13.7.2 The refine's writetype Statement
13.7.3 The refine's access Statement
13.7.4 The refine's description Statement
13.8 Usage Example
14. SMIng Core Modules
14.1 IRTF-NMRG-SMING
14.2 IRTF-NMRG-SMING-TYPES
14.3 IRTF-NMRG-SMING-EXTENSIONS
15. Extending a Module
16. SMIng Language Extensibility
17. Module Conversions
17.1 Converting SMIv2 to SMIng
17.2 Converting SMIng to SMIv2
17.3 SMIv1
18. Security Considerations
19. Acknowledgements
§ References
§ Author's Address
A. The SMIng ABNF grammar
B. Glossary



 TOC 

1. Introduction

Management information is viewed as a collection of managed objects, residing in a virtual information store, termed the Management Information Base (MIB). Collections of related objects are defined in MIB modules. These modules are written conforming to a specification language, the Structure of Management Information (SMI). There are different versions of the SMI. SMIv1 [5], [6], [7] and SMIv2 [2], [3], [4] are based on adapted subsets of OSI's Abstract Syntax Notation One, ASN.1 [9]. It is the purpose of this document to define a successor of SMIv1 and SMIv2, the SMIng, in a self-contained way independent from other standardization bodies' documents.

The Information Model gives an overview of some basic concepts of the information model while the subsequent sections present the concepts of SMIng: the base types, the SMIng file structure, and all SMIng statements in detail. SMIng Core Modules contains three core modules that are part of the SMIng specification. Extending a Module lists rules to follow when changes are applied to a module. One flexible feature of SMIng is its extensibility which is described in SMIng Language Extensibility. Finally, Module Conversions discusses conversions of SMIv2 modules to SMIng and vice versa. The SMIng ABNF grammar contains the grammar of SMIng in ABNF [8] notation.

1.1 Terminology

Many terms in SMIv1 and SMIv2 are derived from ASN.1. In some cases, SMIv1/v2 uses different terms for equal or similar language items without precise definitions. Glossary presents a glossary of terms used throughout this document and in related SMIng documents. Also refer to the glossary and The SMIng ABNF grammar to get detailed information on the syntax of single language items where not explained in place.

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 [1].

1.2 Relation to SNMP

Although SMIng is primarily intended to be applied to the SNMP management framework [10], SMIng is designed to have as few relations to a specific management protocol as possible. However, there are some implications of SNMP on SMIv2 that have to be retained in SMIng:



 TOC 

2. The Information Model

Internet management is based on the model of "managed objects". A managed object represents a class of any real or synthesized variable of systems that are to be managed. Those objects are organized hierarchically in an "object identifier tree", where only leaf nodes may represent objects.

Nodes may also identify tables, row definitions of tables, notifications, groups of objects and/or notifications, compliance statements, modules or other information. Each node is identified by an unique "object identifier" value which is an ordered list of non-negative numbers, named "sub-identifiers", where 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.

The SMI in general, and SMIng in particular, is the information model used to define and organize the structure of managed objects and related information. Thus, SMIng describes a language designed to specify management information in a way readable to computer programs, named MIB compilers, as well as to human readers.

Related management information is defined in MIB modules. A module may refer to definitions from other modules by importing identifiers from those modules. Each module may serve one or multiple purposes:

This classification scheme does not imply a rigid taxonomy. For example, a "standard" module will normally include definitions of managed objects and a compliance statement. Similarly, an "enterprise-specific" module might include definitions of managed objects and a capability statement based on an extension. Of course, a "standard" module may not contain capability statements.

Each module is identified by an upper-case identifier. The names of all standard modules must be unique (but different versions of the same module should have the same name). Developers of enterprise modules are encouraged to choose names for their modules that will have a low probability of colliding with standard or other enterprise modules, e.g. by using the enterprise or organization name as a prefix.

2.1 Identifiers

Identifiers are used to identify different kinds of SMIng items by name. These names are valid in a namespace which is dependent on the SMIng item. Those items are

Each identifier starts with an upper-case or lower-case character, dependent on the kind of SMIng item, followed by zero or more letters, digits, and hyphens.

For all identifiers of a single kind of item defined in a namespace, the identifier MUST be unique and SHOULD NOT only differ in case. Identifiers MUST NOT exceed 64 characters in length. Furthermore, the set of all identifiers defined in all modules of a single standardization body or organization SHOULD be unique and mnemonic. This promotes a common language for humans to use when discussing a module.

To reference an item that is defined in the local module, its definition MUST sequentially precede the reference. Thus, there MUST NOT be any forward references, except in two cases:

  1. The optional module's `identity' statement, which is located near the head of a module, specifies an identity node, which is defined in a subsequent section of the local module.
  2. The specification of table indexing objects in a table row may include objects that cannot be defined without the definition of the current table row. Hence table indexing statements are allowed to include forward references.

To reference an item, that is defined in an external module it MUST be imported into the local module's namespace (The module's import Statement). Identifiers that are neither defined nor imported MUST NOT be visible in the local module. On the other hand, all items defined in a module are implicitly exported.

Note when identifiers from external modules are referenced, there is the possibility of name collisions. As such, if different items with the same identifier are imported or if imported identifiers collide with identifiers of locally defined items, then this ambiguity is resolved by prefixing those identifiers with the names of their modules and the namespace operator `::', i.e. `Module::item'. Of course, this notation can be used to refer to identifiers even when there is no name collision.

Note that SMIng language keywords MUST NOT be imported. The main set of keywords are SMIng statements and base types. See the `...Keyword' rules of the SMIng ABNF grammar in The SMIng ABNF grammar for a list of those keywords.

Finally, by convention, if the identifier refers to an object with a counter type (Counter32 or Counter64, derived from Unsigned32 and Unsigned64) then the identifier used for the object SHOULD denote plurality.

2.2 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

Note that the renaming of the Commite Consultatif International de Telegraphique et Telephonique (CCITT) to International Telecommunications Union (ITU) had no consequence on the names used in the object identifier tree.

The root of the subtree administered by the Internet Assigned Numbers Authority (IANA) for the Internet is `1.3.6.1' which is assigned with the identifier `internet'. That is, the Internet subtree of object identifiers starts with the prefix `1.3.6.1.'.

Several branches underneath this subtree are used for network management:

The `mgmt' (internet.2) subtree is used to identify "standard" information.

The `experimental' (internet.3) subtree is used to identify information being designed by working groups of the IETF or IRTF. If a module produced by a working group becomes a "standard" module then at the very beginning of its entry onto the Internet standards track, the information is moved under the mgmt subtree.

The `private' (internet.4) subtree is used to identify information defined unilaterally. The `enterprises' (private.1) subtree beneath private is used, among other things, to permit providers of networking subsystems to register models of their products.

These and some other nodes are defined in the SMIng standard module IRTF-NMRG-SMING.

2.3 Kinds of Nodes

Each node in the object identifier tree may be of a single kind which may represent management information or not:

2.4 Scalar and Columnar Objects' Instances

Instances of managed objects are identified by appending an instance-identifier to the object's object identifier. Scalar objects and columnar objects use different ways to construct the instance-identifier.

Scalar objects have zero or one object instance. If it exists, it is identified by appending a single `0' sub-identifier to the object identifier of the scalar object.

Within tables, different instances of the same columnar object are identified by appending a sequence of one or more sub-identifiers to the object identifier of the columnar object which consists of the values of object instances that unambiguously distinguish a table row. These indexing objects can be columnar objects of the same and/or another table, but MUST NOT be scalar objects. Multiple applications of the same object in a single table indexing specification are strongly discouraged.

The base types (Base Types and Derived Types) of the indexing objects indicate how to form the instance-identifier:

Note that compact encoding can only be applied to an object having a variable-length syntax (e.g., variable-length strings, bits objects or object identifier-valued objects). Further, compact encoding can only be associated with the last object in a list of indexing objects. 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 use of 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.

Objects which are both specified for indexing in a row and also columnar objects of the same row are termed auxiliary objects. Auxiliary objects SHOULD be non-accessible, except in the following circumstances:



 TOC 

3. Base Types and Derived Types

SMIng has a minimal but complete set of base types, similar to those of many programming languages, but with some differences due to special requirements from the management information model described in The Information Model.

Additional types may be defined, derived from those base types and even from other derived types. Derived types may use subtyping to formally restrict the possible values. A set of derived types commonly used in the SNMP framework is defined in the SMIng standard module IRTF-NMRG-SMING-TYPES.

Note that types can also be restricted "inline" in object definitions (The scalar Statement, The table row's column Statement) or in refinements of compliance statements (The compliance Statement) without referring an explicitly defined type.

The different base types and its derived types allow different kinds of subtyping, namely size restrictions and range restrictions. See the following sections on base types (OctetString through Bits) for details.

3.1 OctetString

The OctetString base type represents arbitrary binary or textual data. Although SMIng has a theoretical size limitation of 2^32-1 (4294967295) octets for this base type, MIB designers should realize that there may be implementation and interoperability limitations for sizes in excess of 255 octets.

Values of octet strings may be denoted as textual data enclosed in double quotes or as arbitrary binary data denoted as a `0x'-prefixed hexadecimal value of arbitrary but even length, where each pair of hexadecimal digits represents a single octet. Letters in hexadecimal values MAY be upper-case but lower-case characters are RECOMMENDED. Textual data may contain any number (possibly zero) of any 7-bit displayable ASCII characters except double quote `"', including tab characters, spaces and line terminator characters (nl or cr & nl). Textual data may span multiple lines, where each subsequent line prefix containing only white space up to the column where the first line's data starts SHOULD be skipped by parsers for a better text formatting.

When defining a type derived (directly or indirectly) from the OctetString base type, the size in octets may be restricted by appending a list of size ranges or explicit size values, separated by pipe `|' characters and the whole list enclosed in parenthesis. A size range consists of a lower bound, two consecutive dots `..' and an upper bound. Each value can be given in decimal or `0x'-prefixed hexadecimal notation. Of course, size restricting values MUST NOT be negative. If multiple values or ranges are given, they all MUST be disjunct and SHOULD be in ascending order. If a size restriction is applied to an already size restricted octet string the new restriction MUST be more limiting, that is raising the lower bounds, reducing the upper bounds, reducing the alternative size choices, or splitting ranges into multiple ranges with intermediate gaps.

Value Examples:

  "This is a multiline    
   textual data example."         // legal
  "This is "illegally" quoted."   // illegal quotes
  "But this is 'ok'."             // legal apostrophe quoting
  ""                              // legal zero length
  0x123                           // illegal odd hex length
  0x534d496e670a                  // legal octet string
            

Restriction Examples:

  OctetString (0 | 4..255)        // legal size spec
  OctetString (4)                 // legal exact size
  OctetString (-1 | 1)            // illegal negative size
  OctetString (1 | 1..10)         // illegal overlapping
            

3.2 ObjectIdentifier

The ObjectIdentifier base type represents any object identifier value, which is a list of up to 128 numbers, named sub-identifiers. Each sub-identifier has a value between 0 and 2^32-1 (4294967295).

Values of object identifiers may be denoted as a sequence of numerical sub-identifier values (decimal or `0x'-prefixed hexadecimal) separated by single dots and without any intermediate white space. Alternatively (and preferred in most cases), the first element may be a previously defined or imported lower-case identifier, representing a static object identifier prefix while the total number of sub-identifiers MUST NOT exceed 128 including the expanded identifier.

Object identifier derived types cannot be restricted in any way.

Value Examples:

  0                           // legal single subid
  1.3.6.1                     // legal numerical oid
  mib-2.1                     // legal oid with identifier prefix
  internet.4.1.0x0627.0x01    // legal oid with hex subids
  iso.-1                      // illegal negative subid
  iso.org.6                   // illegal non-heading identifier
  IF-MIB::ifNumber.0          // legel fully quallified instance oid
            

3.3 Integer32

The Integer32 base type represents integer values between -2^31 (-2147483648) and 2^31-1 (2147483647).

Values of type Integer32 may be denoted as decimal or hexadecimal numbers, where only decimal numbers can be negative. Other decimal numbers than zero MUST NOT have leading zero digits. Hexadecimal numbers are prefixed by `0x' and MUST have an even number of hexadecimal digits, where letters MAY be upper-case but lower-case characters are RECOMMENDED.

When defining a type derived (directly or indirectly) from the Integer32 base type, the set of possible values may be restricted by appending a list of ranges or explicit values, separated by pipe `|' characters and the whole list enclosed in parenthesis. A range consists of a lower bound, two consecutive dots `..' and an upper bound. Each value can be given in decimal or `0x'-prefixed hexadecimal notation. If multiple values or ranges are given they all MUST be disjunct and SHOULD be in ascending order. If a value restriction is applied to an already restricted type the new restriction MUST be more limiting, that is raising the lower bounds, reducing the upper bounds, reducing the alternative choices, or splitting ranges into multiple ranges with intermediate gaps.

Value Examples:

  015                         // illegal leading zero
  -123                        // legal negative value
  - 1                         // illegal intermediate space
  0xabc                       // illegal hexadecimal value length
  -0xff                       // illegal sign on hex value
  0x80000000                  // illegal value, too large
  0xf00f                      // legal hexadecimal value
            

Restriction Examples:

  Integer32 (0 | 5..10)       // legal range spec
  Integer32 (4..8 | 5..10)    // illegal overlapping
            

3.4 Integer64

The Integer64 base type represents integer values between -2^63 (-9223372036854775808) and 2^63-1 (9223372036854775807).

Values of type Integer64 may be denoted as decimal or hexadecimal numbers, where only decimal numbers can be negative. Other decimal numbers than zero MUST NOT have leading zero digits. Hexadecimal numbers are prefixed by `0x' and MUST have an even number of hexadecimal digits, where letters MAY be upper-case but lower-case characters are RECOMMENDED.

When defining a type derived (directly or indirectly) from the Integer64 base type, the set of possible values may be restricted by appending a list of ranges or explicit values, separated by pipe `|' characters and the whole list enclosed in parenthesis. A range consists of a lower bound, two consecutive dots `..' and an upper bound. Each value can be given in decimal or `0x'-prefixed hexadecimal notation. If multiple values or ranges are given they all MUST be disjunct and SHOULD be in ascending order. If a value restriction is applied to an already restricted type the new restriction MUST be more limiting, that is raising the lower bounds, reducing the upper bounds, reducing the alternative choices, or splitting ranges into multiple ranges with intermediate gaps.

Value Examples:

  015                         // illegal leading zero
  -123                        // legal negative value
  - 1                         // illegal intermediate space
  0xabc                       // illegal hexadecimal value length
  -0xff                       // illegal sign on hex value
  0x80000000                  // legal value
            

Restriction Examples:

  Integer64 (0 | 5..10)       // legal range spec
  Integer64 (4..8 | 5..10)    // illegal overlapping
            

3.5 Unsigned32

The Unsigned32 base type represents positive integer values between 0 and 2^32-1 (4294967295).

Values of type Unsigned32 may be denoted as decimal or hexadecimal numbers. Other decimal numbers than zero MUST NOT have leading zero digits. Hexadecimal numbers are prefixed by `0x' and MUST have an even number of hexadecimal digits, where letters MAY be upper-case but lower-case characters are RECOMMENDED.

When defining a type derived (directly or indirectly) from the Unsigned32 base type, the set of possible values may be restricted by appending a list of ranges or explicit values, separated by pipe `|' characters and the whole list enclosed in parenthesis. A range consists of a lower bound, two consecutive dots `..' and an upper bound. Each value can be given in decimal or `0x'-prefixed hexadecimal notation. If multiple values or ranges are given they all MUST be disjunct and SHOULD be in ascending order. If a value restriction is applied to an already restricted type the new restriction MUST be more limiting, that is raising the lower bounds, reducing the upper bounds, reducing the alternative choices, or splitting ranges into multiple ranges with intermediate gaps.

Value Examples:

  015                         // illegal leading zero
  -123                        // illegal negative value
  0xabc                       // illegal hexadecimal value length
  0x80000000                  // legal hexadecimal value
  0x8080000000                // illegal value, too large]]>
            

Restriction Examples:

  Unsigned32 (0 | 5..10)       // legal range spec
  Unsigned32 (4..8 | 5..10)    // illegal overlapping
            

3.6 Unsigned64

The Unsigned64 base type represents positive integer values between 0 and 2^64-1 (18446744073709551615).

Values of type Unsigned64 may be denoted as decimal or hexadecimal numbers. Other decimal numbers than zero MUST NOT have leading zero digits. Hexadecimal numbers are prefixed by `0x' and MUST have an even number of hexadecimal digits, where letters MAY be upper-case but lower-case characters are RECOMMENDED.

When defining a type derived (directly or indirectly) from the Unsigned64 base type, the set of possible values may be restricted by appending a list of ranges or explicit values, separated by pipe `|' characters and the whole list enclosed in parenthesis. A range consists of a lower bound, two consecutive dots `..' and an upper bound. Each value can be given in decimal or `0x'-prefixed hexadecimal notation. If multiple values or ranges are given they all MUST be disjunct and SHOULD be in ascending order. If a value restriction is applied to an already restricted type the new restriction MUST be more limiting, that is raising the lower bounds, reducing the upper bounds, reducing the alternative choices, or splitting ranges into multiple ranges with intermediate gaps.

Value Examples:

  015                         // illegal leading zero
  -123                        // illegal negative value
  0xabc                       // illegal hexadecimal value length
  0x8080000000                // legal hexadecimal value
            

Restriction Examples:

  Unsigned64 (1..10000000000) // legal range spec
            

3.7 Float32

The Float32 base type represents floating point values of single precision as described by [11].

Values of type Float32 may be denoted as a decimal fraction with an optional exponent as known from many programming languages. See the grammar rule `floatValue' of The SMIng ABNF grammar for the detailed syntax. Special values are `snan' (signaling Not-a-Number), `qnan' (quiet Not-a-Number), `neginf' (negative infinity), and `posinf' (positive infinity). Note that -0.0 and +0.0 are different floating point values. 0.0 is equal to +0.0.

When defining a type derived (directly or indirectly) from the Float32 base type, the set of possible values may be restricted by appending a list of ranges or explicit values, separated by pipe `|' characters and the whole list enclosed in parenthesis. A range consists of a lower bound, two consecutive dots `..' and an upper bound. If multiple values or ranges are given they all MUST be disjunct and SHOULD be in ascending order. If a value restriction is applied to an already restricted type the new restriction MUST be more limiting, that is raising the lower bounds, reducing the upper bounds, reducing the alternative choices, or splitting ranges into multiple ranges with intermediate gaps. The special values `snan', `qnan', `neginf', and `posinf' must be explicitly listed in restrictions if they shall be included, where `snan' and `qnan' cannot be used in ranges.

Note that encoding is not subject to this specification. It has to be described by protocols that transport objects of type Float32. Note also that most floating point encodings disallow the representation of many values that can be written as decimal fractions as used in SMIng for human readability. Therefore, explicit values in floating point type restrictions should be handled with care.

Value Examples:

  00.1                       // illegal leading zero
  3.1415                     // legal value
  -2.5E+3                    // legal negative exponential value
            

Restriction Examples:

  Float32 (-1.0..1.0)        // legal range spec
  Float32 (1 | 3.3 | 5)      // legal, probably unrepresentable 3.3
  Float32 (-10.0..10.0 | 0)  // illegal overlapping
            

3.8 Float64

The Float64 base type represents floating point values of double precision as described by [11].

Values of type Float64 may be denoted as a decimal fraction with an optional exponent as known from many programming languages. See the grammar rule `floatValue' of The SMIng ABNF grammar for the detailed syntax. Special values are `snan' (signaling Not-a-Number), `qnan' (quiet Not-a-Number), `neginf' (negative infinity), and `posinf' (positive infinity). Note that -0.0 and +0.0 are different floating point values. 0.0 is equal to +0.0.

When defining a type derived (directly or indirectly) from the Float64 base type, the set of possible values may be restricted by appending a list of ranges or explicit values, separated by pipe `|' characters and the whole list enclosed in parenthesis. A range consists of a lower bound, two consecutive dots `..' and an upper bound. If multiple values or ranges are given they all MUST be disjunct and SHOULD be in ascending order. If a value restriction is applied to an already restricted type the new restriction MUST be more limiting, that is raising the lower bounds, reducing the upper bounds, reducing the alternative choices, or splitting ranges into multiple ranges with intermediate gaps. The special values `snan', `qnan', `neginf', and `posinf' must be explicitly listed in restrictions if they shall be included, where `snan' and `qnan' cannot be used in ranges. If 0.0 is included, -0.0 will also be.

Note that encoding is not subject to this specification. It has to be described by protocols that transport objects of type Float64. Note also that most floating point encodings disallow the representation of many values that can be written as decimal fractions as used in SMIng for human readability. Therefore, explicit values in floating point type restrictions should be handled with care.

Value Examples:

  00.1                       // illegal leading zero
  3.1415                     // legal value
  -2.5E+3                    // legal negative exponential value
            

Restriction Examples:

  Float64 (-1.0..1.0)        // legal range spec
  Float64 (1 | 3.3 | 5)      // legal, probably unrepresentable 3.3
  Float64 (-10.0..10.0 | 0)  // illegal overlapping
            

3.9 Float128

The Float128 base type represents floating point values of quadruple precision as described by [11].

Values of type Float128 may be denoted as a decimal fraction with an optional exponent as known from many programming languages. See the grammar rule `floatValue' of The SMIng ABNF grammar for the detailed syntax. Special values are `snan' (signaling Not-a-Number), `qnan' (quiet Not-a-Number), `neginf' (negative infinity), and `posinf' (positive infinity). Note that -0.0 and +0.0 are different floating point values. 0.0 is equal to +0.0.

When defining a type derived (directly or indirectly) from the Float128 base type, the set of possible values may be restricted by appending a list of ranges or explicit values, separated by pipe `|' characters and the whole list enclosed in parenthesis. A range consists of a lower bound, two consecutive dots `..' and an upper bound. If multiple values or ranges are given they all MUST be disjunct and SHOULD be in ascending order. If a value restriction is applied to an already restricted type the new restriction MUST be more limiting, that is raising the lower bounds, reducing the upper bounds, reducing the alternative choices, or splitting ranges into multiple ranges with intermediate gaps. The special values `snan', `qnan', `neginf', and `posinf' must be explicitly listed in restrictions if they shall be included, where `snan' and `qnan' cannot be used in ranges. If 0.0 is included, -0.0 will also be.

Note that encoding is not subject to this specification. It has to be described by protocols that transport objects of type Float128. Note also that most floating point encodings disallow the representation of many values that can be written as decimal fractions as used in SMIng for human readability. Therefore, explicit values in floating point type restrictions should be handled with care.

Value Examples:

  00.1                       // illegal leading zero
  3.1415                     // legal value
  -2.5E+3                    // legal negative exponential value
            

Restriction Examples:

  Float128 (-1.0..1.0)       // legal range spec
  Float128 (1 | 3.3 | 5)     // legal, probably unrepresentable 3.3
  Float128 (-10.0..10.0 | 0) // illegal overlapping
            

3.10 Enumeration

The Enumeration base type represents values from a set of integers in the range between -2^31 (-2147483648) and 2^31-1 (2147483647), where each value has an assigned name. The list of those named numbers has to be comma-separated, enclosed in parenthesis and appended to the `Enumeration' keyword. Each named number is denoted by its lower-case identifier followed by the assigned integer value, denoted as a decimal or `0x'-prefixed hexadecimal number, enclosed in parenthesis. Every name and every number in an enumeration type MUST be unique. It is RECOMMENDED that values start at 1 and be numbered contiguously.

Values of enumeration types may be denoted as decimal or `0x'-prefixed hexadecimal numbers or preferably as their assigned names.

When defining a type derived (directly or indirectly) from an enumeration type, the set of named numbers may be restricted by removing one or more named numbers. But no named numbers may be added or changed regarding its name, value, or both.

Type and Value Examples:

  Enumeration (up(1), down(2), testing(3))

  0                           // illegal, value 0 out of range
  up                          // legal value given by name
  2                           // legal value given by number
            

3.11 Bits

The Bits base type represents bit sets. That is, a Bits value is a set of flags identified by small integer numbers starting at 0. Each bit number has an assigned name. The list of those named numbers has to be comma-separated, enclosed in parenthesis and appended to the `Bits' keyword. Each named number is denoted by its lower-case identifier followed by the assigned integer value, denoted as a decimal or `0x'-prefixed hexadecimal number, enclosed in parenthesis. Every name and every number in a bits type MUST be unique. It is RECOMMENDED that numbers start at 0 and be numbered contiguously.

Values of bits types may be denoted as a comma-separated list of decimal or `0x'-prefixed hexadecimal numbers or preferably their assigned names enclosed in parenthesis. There MUST NOT be any element (by name or number) listed more than once. It is RECOMMENDED to list elements in ascending order, although the order is semantically irrelevant.

When defining a type derived (directly or indirectly) from a bits type, the set of named numbers may be restricted by removing one or more named numbers. But no named numbers may be added or changed regarding its name, value, or both.

Type and Value Examples:

  Bits (readable(0), writeable(1), executable(2))

  ()                          // legal empty value
  (readable, writeable, 2)    // legal value
  (0, readable, executable)   // illegal, readable(0) appears twice
  (writeable, 4)              // illegal, element 4 out of range
            

3.12 Display Formats

Some SMIng definitions, namely scalar and columnar object definitions and type definitions, allow the specification of a format to be used, when a value of that object or an object of that type is displayed. Format specifications are represented as textual data.

When the object or type has an underlying base type of Integer32, Integer64, Unsigned32, or Unsigned64, the format consists of an integer-format specification, containing two parts. The first part is a single character suggesting a display format, either: `x' for hexadecimal, or `d' for decimal, or `o' for octal, or `b' for binary. For all types, when rendering the value, leading zeros are omitted, and for negative values, a minus sign is rendered immediately before the digits. The second part is always omitted for `x', `o' and `b', and need not be present for `d'. If present, the second part starts with a hyphen and is followed by a decimal number, which defines the implied decimal point when rendering the value. For example `d-2' suggests that a value of 1234 be rendered as `12.34'.

When the object or type has an underlying base type of OctetString, the format consists of one or more octet-format specifications. Each specification consists of five parts, with each part using and removing zero or more of the next octets from the value and producing the next zero or more characters to be displayed. The octets within the value are processed in order of significance, most significant first.

The five parts of a octet-format specification are:

  1. the (optional) repeat indicator; if present, this part is a `*', and indicates that the current octet of the value is to be used as the repeat count. The repeat count is an unsigned integer (which may be zero) which specifies how many times the remainder of this octet-format specification should be successively applied. If the repeat indicator is not present, the repeat count is one.
  2. the octet length: one or more decimal digits specifying the number of octets of the value to be used and formatted by this octet-specification. Note that the octet length can be zero. If less than this number of octets remain in the value, then the lesser number of octets are used.
  3. the display format, either: `x' for hexadecimal, `d' for decimal, `o' for octal, `a' for ASCII, or `t' for UTF-8 [12]. If the octet length part is greater than one, and the display format part refers to a numeric format, then network byte-ordering (big-endian encoding) is used interpreting the octets in the value. The octets processed by the `t' display format do not necessarily form an integral number of UTF-8 characters. Trailing octets which do not form a valid UTF-8 encoded character are discarded.
  4. the (optional) display separator character; if present, this part is a single character which is produced for display after each application of this octet-specification; however, this character is not produced for display if it would be immediately followed by the display of the repeat terminator character for this octet specification. This character can be any character other than a decimal digit and a `*'.
  5. the (optional) repeat terminator character, which can be present only if the display separator character is present and this octet specification begins with a repeat indicator; if present, this part is a single character which is produced after all the zero or more repeated applications (as given by the repeat count) of this octet specification. This character can be any character other than a decimal digit and a `*'.

Output of a display separator character or a repeat terminator character is suppressed if it would occur as the last character of the display.

If the octets of the value are exhausted before all the octet format specification have been used, then the excess specifications are ignored. If additional octets remain in the value after interpreting all the octet format specifications, then the last octet format specification is re-interpreted to process the additional octets, until no octets remain in the value.

Note that for some types (e.g. ObjectIdentifier) no format specifications are defined and SHOULD be omitted. Implementations MUST ignore format specifications they cannot interpret. Also note that the SMIng grammar (The SMIng ABNF grammar) does not specify the syntax of format specifications.

Display Format Examples:

  Base Type   Format              Example Value    Rendered Value
  ----------- ------------------- ---------------- -----------------
  OctetString 255a                "Hello World."   Hello World.
  OctetString 1x:                 "Hello!"         48:65:6c:6c:6f:21
  OctetString 1d:1d:1d.1d,1a1d:1d 0x0d1e0f002d0400 13:30:15.0,-4:0
  OctetString 1d.1d.1d.1d/2d      0x0a0000010400   10.0.0.1/1024
  OctetString *1x:/1x:            0x02aabbccddee   aa:bb/cc:dd:ee
  Integer32   d-2                 1234             12.34
            



 TOC 

4. The SMIng File Structure

The topmost container of SMIng information is a file. An SMIng file may contain zero, one or more modules. It is RECOMMENDED to separate modules into files named by their modules, where possible. Though, for dedicated purposes it may be reasonable to collect several modules in a single file.

The top level SMIng construct is the `module' statement (The module Statement) that defines a single MIB module. A module contains a sequence of sections in an obligatory order with different kinds of definitions. Whether these sections contain statements or remain empty mainly depends on the purpose of the module (see The Information Model).

4.1 Comments

Comments can be included at any position in an SMIng file, except in between the characters of a single token like those of a quoted strings. However, it is RECOMMENDED that all substantive descriptions be placed within an appropriate description clause.

Comments commence with a pair of adjacent slashes `//' and end at the end of the line.

4.2 Statements and Arguments

SMIng has a very small set of basic grammar rules based on the concept of statements. Each statement starts with a lower-case keyword identifying the statement followed by a number (possibly zero) of arguments. An argument may be quoted text, an identifier, a value of any base type, a list of identifiers enclosed in parenthesis `( )' or a statement block enclosed in curly braces `{ }'. Since statement blocks are valid arguments, it is possible to nest statement sequences. Each statement is terminated by a semicolon `;'.

The core set of statements may be extended using the SMIng `extension' statement. See The extension Statement and SMIng Language Extensibility for details.

At places where a statement is expected, but an unknown lower-case word is read, those statements MUST be skipped up to the proper semicolon, including nested statement blocks.



 TOC 

5. The module Statement

The `module' statement is used as a container of all definitions of a single SMIng MIB module. It gets two arguments: an upper-case module name and a statement block that contains mandatory and optional statements and sections of statements in an obligatory order:

        module <MODULE-NAME> {
        
            <optional import statements>
            <organization statement>
            <contact statement>
            <description statement>
            <optional reference statement>
            <at least one revision statement>
            <optional identity statement>

            <optional extension statements>

            <optional typedef statements>

            <optional node/scalar/table statements>

            <optional notification statements>

            <optional group statements>

            <optional compliance statements>

        };

The optional `import' statements are followed by the mandatory `organization', `contact', and `description' statements and the optional `reference' statement, which in turn are followed by the mandatory `revision' statements. This part defines the module's meta information while the following sections contain its main definitions.

See the `moduleStatement' rule of the SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the `module' statement.

5.1 The module's import Statement

The optional module's `import' statement is used to import descriptors from external modules into the local module's namespace. It gets two arguments: the name of the external module and a comma-separated list of one or more identifiers to be imported enclosed in parenthesis.

Multiple `import' statements for the same module but with disjunct lists of identifiers are allowed, though NOT RECOMMENDED. Anyhow, the same identifier from the same module MUST NOT be imported multiple times. To import identifiers with the same name from different modules might be necessary and is allowed. To distinguish them in the local module, they have to be referred by qualified names. It is NOT RECOMMENDED to import identifiers not used in the local module.

See the `importStatement' rule of the SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the `import' statement.

5.2 The module's organization Statement

The module's `organization' statement, which must be present, gets one argument which is used to specify a textual description of the organization(s) under whose auspices this module was developed.

5.3 The module's contact Statement

The module's `contact' statement, which must be present, gets one argument which is used to specify the name, postal address, telephone number, and electronic mail address of the person to whom technical queries concerning this revision of this module should be sent.

5.4 The module's description Statement

The module's `description' statement, which must be present, gets one argument which is used to specify a high-level textual description of the contents of this module.

5.5 The module's reference Statement

The module's `reference' statement, which need not be present, gets one argument which is used to specify a textual cross-reference to some other document, either another module which defines related management information, or some other document which provides additional information relevant to this module.

5.6 The module's revision Statement

The module's `revision' statement is repeatedly used to specify the editorial revisions of the module, including the initial revision. It gets one argument which is a statement block that holds detailed information in an obligatory order. A module MUST have at least one initial `revision' statement. For every editorial change, a new one MUST be added in front of the revisions sequence, so that all revisions are in reverse chronological order.

See the `revisionStatement' rule of the SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the `revision' statement.

5.6.1 The revision's date Statement

The revision's `date' statement, which must be present, gets one argument which is used to specify the date and time of the revision in the format `YYYY-MM-DD HH:MM' or `YYYY-MM-DD' which implies the time `00:00'. The time is always given in UTC.

See the `date' rule of the SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the revision's `date' statement.

5.6.2 The revision's description Statement

The revision's `description' statement, which must be present, gets one argument which is used to specify a high-level textual description of the revision.

5.7 The module's identity Statement

The module's `identity' statement, which need not be present, gets one argument which specifies a node identifier within the local module, so that the object identifier of this node can be used to identify the module.

5.8 Usage Example

Consider how a skeletal MIB module might be constructed: e.g.,

module FIZBIN-MIB {
 
  import IRTF-NMRG-SMING (experimental);
 
  organization      
            "IETF SNMPv2 Working Group,
             IRTF Network Management Research Group (NMRG)";
 
  contact           
            "        Frank Strauss
             
             Postal: TU Braunschweig
                     Bueltenweg 74/75
                     38106 Braunschweig
                     DE
             
              Phone: +49 531 391-3266
              EMail: strauss@ibr.cs.tu-bs.de";
 
  description       
            "The MIB module for entities implementing
             the xxxx protocol.";

  reference
            "RFC 2578, Section 5.7.";

  revision {
    date            "1999-09-28";
    description     
            "Conversion from SMIv2 to SMIng.";
  };
  revision {
    date            "1995-05-24 18:11";
    description     
            "Revision for RFC 1902.";
  };
  revision {
    date            "1992-10-07 04:33";
    description     
            "The initial version of this MIB module,
             published in RFC 1442.";
  };

  identity fizbin;
 
  // ... further definitions ...

}; // end of module FIZBIN-MIB.


 TOC 

6. The extension Statement

The `extension' statement is used to define new statements to be used in the local module following this extension statement definition or in external modules that may import this extension statement definition. The `extension' statement gets two arguments: a lower-case extension statement identifier and a statement block that holds detailed extension information in an obligatory order.

Extension statement identifiers SHOULD NOT contain any upper-case characters or hyphens.

Note that the SMIng extension feature does not allow to formally specify the context, argument syntax and semantics of an extension. Its only purpose is to declare the existence of an extension and to allow a unique reference to an extension. See SMIng Language Extensibility for detailed information on extensions and IRTF-NMRG-SMING-EXTENSIONS for a common example, the `agentcaps' extension.

See the `extensionStatement' rule of the SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the `extension' statement.

6.1 The extension's status Statement

The extension's `status' statement, which need not be present, gets one argument which is used to specify whether this extension definition is current or historic. The value `current' means that 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 previously implemented. While the value `deprecated' also indicates an obsolete definition, it permits new/continued implementation in order to foster interoperability with older/existing implementations.

If the `status' statement is omitted, the status value `current' is implied.

6.2 The extension's description Statement

The extension's `description' statement, which must be present, gets one argument which is used to specify a high-level textual description of the extension statement.

It is RECOMMENDED to include information on the extension's context, its semantics, and implementation conditions. See also SMIng Language Extensibility.

6.3 The extension's reference Statement

The extension's `reference' statement, which need not be present, gets one argument which is used to specify a textual cross-reference to some other document, either another module which defines related extension definitions, or some other document which provides additional information relevant to this extension.

6.4 The extension's abnf Statement

The extension's `abnf' statement, which need not be present, gets one argument which is used to specify a formal ABNF [8] grammar definition of the extension.

Note that the `abnf' statement should contain only pure ABNF and no additional text, though comments prefixed by semicolon are allowed but should probably be moved to the description statement. Note also that double quotes are not allowed inside textual descriptions which are itself enclosed in double quotes. So they have to be replaced by single quotes.



 TOC 

7. The typedef Statement

The `typedef' statement is used to define new data types to be used in the local module or in external modules. It gets two arguments: an upper-case type identifier and a statement block that holds detailed type information in an obligatory order.

Type identifiers SHOULD NOT consist of all upper-case characters and SHOULD NOT contain hyphens.

See the `typedefStatement' rule of the SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the `typedef' statement.

7.1 The typedef's type Statement

The typedef's `type' statement, which must be present, gets one argument which is used to specify the type from which this type is derived. Optionally, type restrictions may be applied to the new type by appending subtyping information according to the rules of the base type. See Base Types and Derived Types for SMIng base types and their type restrictions.

7.2 The typedef's default Statement

The typedef's `default' statement, which need not be present, gets one argument which is used to specify an acceptable default value for objects of this type. A default value may be used at the discretion of an agent when an object instance is created. That is, the value is a "hint" to implementors.

The value of the `default' statement must, of course, correspond to the (probably restricted) type specified in the typedef's `type' statement.

The default value of a type may be overwritten by a default value of an object of this type.

Note that for some types, default values make no sense, e.g. IRTF-NMRG-SMING-TYPES::Counter32.

7.3 The typedef's format Statement

The typedef's `format' statement, which need not be present, gets one argument which is used to give a hint as to how the value of an instance of an object of this type might be displayed. See Display Formats for a description of format specifications.

If no format is specified, it is inherited from the type given in the `type' statement. On the other hand, the format specification of a type may be overwritten by a format specification of an object of this type.

7.4 The typedef's units Statement

The typedef's `units' statement, which need not be present, gets one argument which is used to specify a textual definition of the units associated with objects of this type.

If no units are specified, they are inherited from the type given in the `type' statement. On the other hand, the units specification of a type may be overwritten by a units specification of an object of this type.

The units specification has to be appropriate for values displayed according to the typedef's format specification, if present. E.g., if the type defines frequency values of type Unsigned64 measured in thousands of Hertz, the format specification should be `d-3' and the units specification should be `Hertz' or `Hz'. If the format specification would be omitted, the units specification should be `Milli-Hertz' or `mHz'. MIB Authors should pay attention to keep format and units specifications of type and object definitions synced. Application implementors MUST NOT implement units specifications without implementing format specifications.

7.5 The typedef's status Statement

The typedef's `status' statement, which need not be present, gets one argument which is used to specify whether this type definition is current or historic. The value `current' means that 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 previously implemented. While the value `deprecated' also indicates an obsolete definition, it permits new/continued implementation in order to foster interoperability with older/existing implementations.

Derived types SHOULD NOT be defined as `current' if their underlying type is `deprecated' or `obsolete'. Similarly, they SHOULD NOT be defined as `deprecated' if their underlying type is `obsolete'. Nevertheless, subsequent revisions of the underlying type cannot be avoided, but SHOULD be taken into account in subsequent revisions of the local module.

If the `status' statement is omitted, the status value `current' is implied.

7.6 The typedef's description Statement

The typedef's `description' statement, which must be present, gets one argument which is used to specify a high-level textual description of the newly defined type.

It is RECOMMENDED to include all semantic definitions necessary for implementation, and to embody any information which would otherwise be communicated in any commentary annotations associated with this type definition.

7.7 The typedef's reference Statement

The typedef's `reference' statement, which need not be present, gets one argument which is used to specify a textual cross-reference to some other document, either another module which defines related type definitions, or some other document which provides additional information relevant to this type definition.

7.8 Usage Examples

  typedef RptrOperStatus {
    type            Enumeration (other(1), ok(2), rptrFailure(3),
                                 groupFailure(4), portFailure(5),
                                 generalFailure(6));
    default         other;       // undefined by default.
    status          deprecated;
    description     
            "A type to indicate the operational state
             of a repeater.";
    reference
            "[IEEE 802.3 Mgt], 30.4.1.1.5, aRepeaterHealthState.";
  };

  typedef DateAndTime {
    type            OctetString (8 | 11);
    format          "2d-1d-1d,1d:1d:1d.1d,1a1d:1d";
    status          current;     // could be omitted
    description
            "A date-time specification.
             ...
             Note that if only local time is known, then timezone
             information (fields 8-10) is not present.";
    reference
            "RFC 2579, SNMPv2-TC.DateAndTime.";
  };

  typedef Frequency {
    type            Unsigned64;
    format          "d-3"
    units           "Hertz";
    description
            "A wide-range frequency specification measured
             in thousands of Hertz.";
  };


 TOC 

8. The node Statement

The `node' statement is used to name and describe a node in the object identifier tree, without associating object information with this node. This may be useful to group definitions in a subtree of related management information, or to uniquely define an identity of arbitrary kind to be referenced in objects of type ObjectIdentifier. 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 SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the `node' statement.

8.1 The node's oid Statement

The node's `oid' statement, which must be present, gets one argument which specifies the object identifier value that is assigned to this node.

8.2 The node's status Statement

The node's `status' statement, which need not be present, gets one argument which is used to specify whether this node definition is current or historic. The value `current' means that 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 previously implemented. While the value `deprecated' also indicates an obsolete definition, it permits new/continued implementation in order to foster interoperability with older/existing implementations.

If the `status' statement is omitted, the status value `current' is implied.

8.3 The node's description Statement

The node's `description' statement, which must be present, gets one argument which is used to specify a high-level textual description of this node.

It is RECOMMENDED to include all semantics and purposes of this node.

8.4 The node's reference Statement

The node's `reference' statement, which need not be present, gets one argument which is used to specify a textual cross-reference to some other document, either another module which defines related nodes, or some other document which provides additional information relevant to this node.

8.5 Usage Examples

  node iso                            { oid 1;                };
  node   org                          { oid iso.3;            };
  node     dod                        { oid org.6;            };
  node       internet                 { oid dod.1;            };

  node   zeroDotZero {
      oid         0.0;
      description "A value used for null identifiers.";
      reference   "RFC 2578, 2. Definitions.";
  };


 TOC 

9. The scalar Statement

The `scalar' statement is used to define a scalar managed object. The `scalar' statement gets two arguments: a lower-case scalar identifier and a statement block that holds detailed object information in an obligatory order.

See the `scalarStatement' rule of the SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the `scalar' statement.

9.1 The scalar's oid Statement

The scalar's `oid' statement, which must be present, gets one argument which specifies the object identifier value that is assigned to this scalar object.

9.2 The scalar's type Statement

The scalar's `type' statement, which must be present, gets one argument which is used to specify the data type of this scalar object. Optionally, type restrictions may be applied to the type by appending subtyping information according to the rules of the base type. See Base Types and Derived Types for SMIng base types and their type restrictions.

9.3 The scalar's access Statement

The scalar's `access' statement, which must be present, gets one argument which is used to specify whether it makes sense to read and/or write an instance of the object, or to include its value in a notification. This is the maximal level of access for the object. This maximal level of access is independent of any administrative authorization policy.

The value `readwrite' indicates that read and write access makes sense. The value `readonly' indicates that read access makes sense, but write access is never possible. The value `notifyonly' indicates an object which is accessible only via a notification.

These values are ordered, from least to greatest access level: `notifyonly', `readonly', `readwrite'.

9.4 The scalar's default Statement

The scalar's `default' statement, which need not be present, gets one argument which is used to specify an acceptable default value for this scalar object. A default value may be used at the discretion of an agent when an object instance is created. That is, the value is a "hint" to implementors.

The value of the `default' statement must, of course, correspond to the (probably restricted) type specified in the scalar's `type' statement.

The scalar's default value overrides the default value of the underlying type definition, if both are present.

Note that for objects of some types, default values make no sense, e.g. IRTF-NMRG-SMING-TYPES::Counter32.

9.5 The scalar's format Statement

The scalar's `format' statement, which need not be present, gets one argument which is used to give a hint as to how the value of an instance of this object might be displayed. See Display Formats for a description of format specifications.

The scalar's format specification overrides the format specification of the underlying type definition if both are present.

9.6 The scalar's units Statement

The scalar's `units' statement, which need not be present, gets one argument which is used to specify a textual definition of the units associated with this scalar object.

The scalar's units specification overrides the units specification of the underlying type definition if both are present.

The units specification has to be appropriate for values displayed according to the scalar's format specification if present. E.g., if the scalar object represents a frequency value of type Unsigned64 measured in thousands of Hertz, the format specification should be `d-3' and the units specification should be `Hertz' or `Hz'. If the format specification would be omitted, the units specification should be `Milli-Hertz' or `mHz'. MIB Authors should pay attention to keep format and units specifications of type and object definitions synced. Application implementors MUST NOT implement units specifications without implementing format specifications.

9.7 The scalar's status Statement

The scalar's `status' statement, which need not be present, gets one argument which is used to specify whether this scalar object definition is current or historic. The value `current' means that 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 previously implemented. While the value `deprecated' also indicates an obsolete definition, it permits new/continued implementation in order to foster interoperability with older/existing implementations.

Scalar objects SHOULD NOT be defined as `current' if their type is `deprecated' or `obsolete'. Similarly, they SHOULD NOT be defined as `deprecated' if their type is `obsolete'. Nevertheless, subsequent revisions of used type definition cannot be avoided, but SHOULD be taken into account in subsequent revisions of the local module.

If the `status' statement is omitted the status value `current' is implied.

9.8 The scalar's description Statement

The scalar's `description' statement, which must be present, gets one argument which is used to specify a high-level textual description of this scalar object.

It is RECOMMENDED to include all semantic definitions necessary for the implementation of this scalar object.

9.9 The scalar's reference Statement

The scalar's `reference' statement, which need not be present, gets one argument which is used to specify a textual cross-reference to some other document, either another module which defines related scalar objects, or some other document which provides additional information relevant to this scalar object.

9.10 Usage Examples

  scalar dialCtlTrapEnable {
    oid             dialCtlConfiguration.2;
    type            Enumeration (enabled(1), disabled(2));
    access          readwrite;
    default         disabled;
    description     
            "This object indicates whether dialCtlPeerCallInformation
             and dialCtlPeerCallSetup traps should be generated for
             all peers. If the value of this object is enabled(1),
             traps will be generated for all peers. If the value
             of this object is disabled(2), traps will be generated
             only for peers having dialCtlPeerCfgTrapEnable set
             to enabled(1).";
  };


 TOC 

10. The table Statement

The `table' statement is used to define the root node of a table. The `table' statement gets two arguments: a lower-case table identifier and a statement block that holds detailed table information in an obligatory order.

See the `tableStatement' rule of the SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the `table' statement.

10.1 The table's oid Statement

The table's `oid' statement, which must be present, gets one argument which specifies the object identifier value that is assigned to this table node.

10.2 The table's status Statement

The table's `status' statement, which need not be present, gets one argument which is used to specify whether this table definition is current or historic. The value `current' means that 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 previously implemented. While the value `deprecated' also indicates an obsolete definition, it permits new/continued implementation in order to foster interoperability with older/existing implementations.

If the `status' statement is omitted the status value `current' is implied.

10.3 The table's description Statement

The table's `description' statement, which must be present, 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.

10.4 The table's reference Statement

The table's `reference' statement, which need not be present, gets one argument which is used to specify a textual cross-reference to some other document, either another module which defines related tables, or some other document which provides additional information relevant to this table.

10.5 The table's row Statement

The table's `row' statement, which must be present, gets two arguments: a lower-case row identifier and a statement block that holds detailed row information in an obligatory order.

See the `rowStatement' rule of the SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the `row' statement.

10.5.1 The row's oid Statement

The row's `oid' statement, which must be present, gets one argument which specifies the object identifier value that is assigned to this table row. Note that the object identifier of a table row MUST be built be the table's object identifier followed by a `1' sub-identifier.

10.5.2 Table Indexing Statements

SMIng offers five methods to supply table indexing information: ordinary tables, table augmentations, sparse table augmentations, table expansions, and reordered tables use different statements to denote their indexing information. Each table row definition must contain exactly one of the following indexing statements.

10.5.2.1 The row's index Statement for Table Indexing

The row's `index' statement, which is used to supply table indexing information of base table rows, gets at least one argument that specifies a comma-separated list of object identifiers, that are used for table indexing, enclosed in parenthesis.

Under some circumstances, an optional `implied' keyword may be added in front of the list to indicate a compact encoding of the last object in the list. See Scalar and Columnar Objects' Instances for details.

10.5.2.2 The row's augments Statement for Table Indexing

The row's `augments' statement, which is used to supply table indexing information of table rows that augment a base table row, gets one argument that specifies the identifier of the table row to be augmented. Note that a row augmentation cannot itself be augmented. Anyhow, a base row may be augmented by multiple row augmentations.

A row augmentation makes instances of subordinate columnar objects identified according to the index specification of the base row corresponding to the row named in the `augments' statement. Further, instances of subordinate columnar objects of a row augmentation exist according to the same semantics as instances of subordinate columnar objects of the base row being augmented. As such, note that creation of a base row implies the correspondent creation of any row augmentations. Row augmentations MUST NOT be used in row creation and deletion operations.

10.5.2.3 The row's sparse Statement for Table Indexing

The row's `sparse' statement, which is used to supply table indexing information of table rows that sparsely augment a base table row, gets one argument that specifies the identifier of the table row to be sparsely augmented. Note that a sparse row augmentation cannot itself be augmented. Anyhow, a base row may be augmented by multiple row augmentations, sparsely or not.

A sparse row augmentation makes instances of subordinate columnar objects identified, if present, according to the index specification of the base row corresponding to the row named in the `sparse' statement. Further, instances of subordinate columnar objects of a sparse row augmentation exist according to the semantics as instances of subordinate columnar objects of the base row and the (non-formal) rules that confine the sparse relationship. As such, note that creation of a sparse row augmentation may be implied by the creation of a base row as well as done by an explicit creation. However, if a base row gets deleted, any dependent sparse row augmentations get also deleted implicitly.

10.5.2.4 The row's reorders Statement for Table Indexing

The row's `reorders' statement is used to supply table indexing information of table rows, that contain exactly the same index objects of a base table row, except in another order. It gets at least two arguments. The first one specifies the identifier of the base table row. The second one specifies a comma-separated list of exactly those object identifiers of the base row's `index' statement, but in the order to be used in this table. Note that a reordered table cannot itself be reordered. Anyhow, a base row may be used for multiple reordered tables.

Under some circumstances, an optional `implied' keyword may be added in front of the list to indicate a compact encoding of the last object in the list. See Scalar and Columnar Objects' Instances for details.

Instances of subordinate columnar objects of a reordered table exist according to the same semantics as instances of subordinate columnar objects of the base row. As such, note that creation of a base row implies the correspondent creation of any related reordered table. Rows or reordered tables MUST NOT be used in row creation and deletion operations.

10.5.2.5 The row's expands Statement for Table Indexing

The row's `expands' statement is used to supply table indexing information of table row expansions. Table row expansions use exactly the same index objects of another row together with additional indexing objects. Thus, the `expands' statement gets at least two arguments. The first one specifies the identifier of the related table row. The second one specifies a comma-separated list of the additional object identifiers used for indexing. Note that an expanded table may itself be expanded, and related rows may be used for multiple table expansions.

Under some circumstances, an optional `implied' keyword may be added in front of the list to indicate a compact encoding of the last object in the list. See Scalar and Columnar Objects' Instances for details.

10.5.3 The row's create Statement

The row's `create' statement, which need not be present, gets no argument. If the `create' statement is present, row creation (and deletion) is possible.

10.5.4 The row's status Statement

The row's `status' statement, which need not be present, gets one argument which is used to specify whether this row definition is current or historic. The value `current' means that 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 previously implemented. While the value `deprecated' also indicates an obsolete definition, it permits new/continued implementation in order to foster interoperability with older/existing implementations.

If the `status' statement is omitted the status value `current' is implied.

10.5.5 The row's description Statement

The row's `description' statement, which must be present, gets one argument which is used to specify a high-level textual description of this table row.

It is RECOMMENDED to include all semantic definitions necessary for the implementation of this table row. Especially, if the row's indexing statement contains objects that are not columnar objects of the row, it SHOULD be described how these objects are used in uniquely identifying instances of the row's columnar objects.

10.5.6 The row's reference Statement

The row's `reference' statement, which need not be present, gets one argument which is used to specify a textual cross-reference to some other document, either another module which defines related table rows, or some other document which provides additional information relevant to this table row.

10.6 The table row's column Statement

The row's `column' statement is used to define a columnar managed object. The `column' statement gets two arguments: a lower-case column identifier and a statement block that holds detailed object information in an obligatory order.

See the `columnStatement' rule of the SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the `column' statement.

10.6.1 The column's oid Statement

The column's `oid' statement, which must be present, gets one argument which specifies the object identifier value that is assigned to this columnar object.

10.6.2 The column's type Statement

The column's `type' statement, which must be present, gets at least one argument which is used to specify the data type of this columnar object. Optionally, type restrictions may be applied to the type by appending subtyping information according to the rules of the base type. See Base Types and Derived Types for SMIng base types and their type restrictions.

10.6.3 The column's access Statement

The column's `access' statement, which must be present, gets one argument which is used to specify whether it makes sense to read and/or write an instance of the object, or to include its value in a notification. This is the maximal level of access for the object. This maximal level of access is independent of any administrative authorization policy.

The value `readwrite' indicates that read and write access makes sense. The value `readonly' indicates that read access makes sense, but write access is never possible. The value `noaccess' indicates an auxiliary object (see Scalar and Columnar Objects' Instances). The value `notifyonly' indicates an object which is accessible only via a notification.

These values are ordered, from least to greatest access level: `noaccess', `notifyonly', `readonly', `readwrite'.

10.6.4 The column's default Statement

The column's `default' statement, which need not be present, gets one argument which is used to specify an acceptable default value for this columnar object. A default value may be used at the discretion of an agent when an object instance is created. That is, the value is a "hint" to implementors.

The value of the `default' statement must, of course, correspond to the (probably restricted) type specified in the column's `type' statement.

The column's default value overrides the default value of the underlying type definition if both are present.

Note that for objects of some types, default values make no sense, e.g. IRTF-NMRG-SMING-TYPES::Counter32.

10.6.5 The column's format Statement

The column's `format' statement, which need not be present, gets one argument which is used to give a hint as to how the value of an instance of this object might be displayed. See Display Formats for a description of format specifications.

The column's format specification overrides the format specification of the underlying type definition if both are present.

10.6.6 The column's units Statement

The column's `units' statement, which need not be present, gets one argument which is used to specify a textual definition of the units associated with this columnar object.

The column's units specification overrides the units specification of the underlying type definition if both are present.

The units specification has to be appropriate for values displayed according to the column's format specification if present. E.g., if the columnar object represents a frequency value of type Unsigned64 measured in thousands of Hertz, the format specification should be `d-3' and the units specification should be `Hertz' or `Hz'. If the format specification would be omitted the units specification should be `Milli-Hertz' or `mHz'. MIB Authors should pay attention to keep format and units specifications of type and object definitions synced. Application implementors MUST NOT implement units specifications without implementing format specifications.

10.6.7 The column's status Statement

The column's `status' statement, which need not be present, gets one argument which is used to specify whether this columnar object definition is current or historic. The value `current' means that 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 previously implemented. While the value `deprecated' also indicates an obsolete definition, it permits new/continued implementation in order to foster interoperability with older/existing implementations.

Columnar objects SHOULD NOT be defined as `current' if their type is `deprecated' or `obsolete'. Similarly, they SHOULD NOT be defined as `deprecated' if their type is `obsolete'. Nevertheless, subsequent revisions of used type definition cannot be avoided, but SHOULD be taken into account in subsequent revisions of the local module.

If the `status' statement is omitted the status value `current' is implied.

10.6.8 The column's description Statement

The column's `description' statement, which must be present, gets one argument which is used to specify a high-level textual description of this columnar object.

It is RECOMMENDED to include all semantic definitions necessary for the implementation of this columnar object.

10.6.9 The column's reference Statement

The column's `reference' statement, which need not be present, gets one argument which is used to specify a textual cross-reference to some other document, either another module which defines related columnar objects, or some other document which provides additional information relevant to this columnar object.

10.7 Usage Example

Consider how one might define a table and its subordinates. (This example uses the RowStatus type defined in IRTF-NMRG-SMING-TYPES.)

  scalar evalSlot {
    oid             eval.1;
    type            Integer32 (0..2147483647);
    access          readonly;
    description     
            "The index number of the first unassigned entry in the
             evaluation table, or the value of zero indicating that
             all entries are assigned.
             
             A management station should create new entries in the
             evaluation table using this algorithm:  first, issue a
             management protocol retrieval operation to determine the
             value of evalSlot; and, second, issue a management
             protocol set operation to create an instance of the
             evalStatus object setting its value to createAndGo(4) or
             createAndWait(5).  If this latter operation succeeds,
             then the management station may continue modifying the
             instances corresponding to the newly created conceptual
             row, without fear of collision with other management
             stations.";
  };

  table evalTable {
    oid             eval.2;
    description     
            "The (conceptual) evaluation table.";
    reference
            "RFC 2578, 7.11.";

    row evalEntry {
      oid           evalTable.1;
      index         (evalIndex);
      create        (evalStatus);
      description   
            "An entry (conceptual row) in the evaluation table.";

      column evalIndex {
        oid         evalEntry.1;
        type        Integer32 (1..2147483647);
        access      noaccess;
        description 
            "The auxiliary variable used for identifying instances of
             the columnar objects in the evaluation table.";
      };

      column evalString {
        oid         evalEntry.2;
        type        DisplayString;
        access      readwrite;
        description 
            "The string to evaluate.";
      };

      column evalValue {
        oid         evalEntry.3;
        type        Integer32;
        access      readonly;
        default     0;
        description 
            "The value when evalString was last evaluated, or zero if
             no such value is available.";
      };

      column evalStatus {
        oid         evalEntry.4;
        type        RowStatus;
        access      readwrite;
        default     active;
        description 
            "The status column used for creating, modifying, and
             deleting instances of the columnar objects in the
             evaluation table.";
      };
    };
  };


 TOC 

11. The notification Statement

The `notification' statement is used to define a notification. It gets two arguments: a lower-case notification identifier and a statement block that holds detailed information in an obligatory order.

See the `notificationStatement' rule of the SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the `notification' statement.

11.1 The notification's oid Statement

The notification's `oid' statement, which must be present, gets one argument which specifies the object identifier value that is assigned to this notification.

11.2 The notification's objects Statement

The notification's `objects' statement, which need not be present, gets one argument which specifies an ordered sequence of objects by their identifiers to be emitted within this notification. The list of objects has to be comma-separated and enclosed in parenthesis.

One and only one object instance for each occurrence of each object must be present, and in the specified order, in every instance of the notification. If the same object occurs multiple times in a notification's `objects' statement, then an object instance is present for each of them. An object specified in this sequence must not have an `access' statement argument of `noaccess'.

Note that an agent is allowed, at its own discretion, to append as many additional objects as it considers useful to the end of the notification (i.e., after the objects defined by the notification's `objects' statement if present).

11.3 The notification's status Statement

The notification's `status' statement, which need not be present, gets one argument which is used to specify whether this notification definition is current or historic. The value `current' means that 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 previously implemented. While the value `deprecated' also indicates an obsolete definition, it permits new/continued implementation in order to foster interoperability with older/existing implementations.

If the `status' statement is omitted the status value `current' is implied.

11.4 The notification's description Statement

The notification's `description' statement, which must be present, gets one argument which is used to specify a high-level textual description of this notification.

It is RECOMMENDED to include all semantic definitions necessary for the implementation of this notification. In particular, it SHOULD be documented which instances of the objects mentioned in the `objects' statement should be contained within notifications of this type.

11.5 The notification's reference Statement

The notification's `reference' statement, which need not be present, gets one argument which is used to specify a textual cross-reference to some other document, either another module which defines related notifications, or some other document which provides additional information relevant to this notification.

11.6 Usage Example

Consider how a configuration change notification might be described:

  node entityMIBTraps      { oid             entityMIB.2;      };

  node entityMIBTrapPrefix { oid             entityMIBTraps.0; };

  notification entConfigChange {
    oid             entityMIBTrapPrefix.1;
    description     
            "An entConfigChange trap is sent when the value of
             entLastChangeTime changes. It can be utilized by an NMS
             to trigger logical/physical entity table maintenance
             polls.  An agent must not generate more than one
             entConfigChange 'trap-event' in a five second period,
             where a 'trap-event' is the transmission of a single
             trap PDU to a list of trap destinations.  If additional
             configuration changes occur within the five second
             'throttling' period then these trap-events should be
             suppressed by the agent. An NMS should periodically
             check the value of entLastChangeTime to detect any
             missed entConfigChange trap-events, e.g. due to
             throttling or transmission loss.";
  };


 TOC 

12. 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 that holds detailed group information in an obligatory order.

Note that the primary application of groups are compliance statements, although they might be referred in other formal or informal documents.

See the `groupStatement' rule of the SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the `group' statement.

12.1 The group's oid Statement

The group's `oid' statement, which must be present, gets one argument which specifies the object identifier value that is assigned to this group.

12.2 The group's members Statement

The group's `members' statement, which must be present, gets one argument which specifies the list of nodes by their identifiers to be contained in this group. The list of nodes has to be comma-separated and enclosed in parenthesis.

12.3 The group's status Statement

The group's `status' statement, which need not be present, gets one argument which is used to specify whether this group definition is current or historic. The value `current' means that the definition is current and valid. The value `obsolete' means the definition is obsolete and the group should no longer be used. While the value `deprecated' also indicates an obsolete definition, it permits new/continued use of this group.

If the `status' statement is omitted the status value `current' is implied.

12.4 The group's description Statement

The group's `description' statement, which must be present, gets one argument which is used to specify a high-level textual description of this group. It is RECOMMENDED to include any relation to other groups.

12.5 The group's reference Statement

The group's `reference' statement, which need not be present, gets one argument which is used to specify a textual cross-reference to some other document, either another module which defines related groups, or some other document which provides additional information relevant to this group.

12.6 Usage Example

The snmpGroup, originally defined in [13], may be described as follows:

  group snmpGroup {
    oid             snmpMIBGroups.8;
    objects         (snmpInPkts, snmpInBadVersions,
                     snmpInASNParseErrs, 
                     snmpSilentDrops, snmpProxyDrops, 
                     snmpEnableAuthenTraps);
    description     
            "A collection of objects providing basic
             instrumentation and control of an agent.";
  };


 TOC 

13. The compliance Statement

The `compliance' statement is used to define a set of compliance requirements, named a `compliance statement'. It gets two arguments: a lower-case compliance identifier and a statement block that holds detailed compliance information in an obligatory order.

See the `complianceStatement' rule of the SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the `compliance' statement.

13.1 The compliance's oid Statement

The compliance's `oid' statement, which must be present, gets one argument which specifies the object identifier value that is assigned to this compliance statement.

13.2 The compliance's status Statement

The compliance's `status' statement, which need not be present, gets one argument which is used to specify whether this compliance statement is current or historic. The value `current' means that the definition is current and valid. The value `obsolete' means the definition is obsolete and no longer specifies a valid definition of conformance. While the value `deprecated' also indicates an obsolete definition, it permits new/continued use of the compliance specification.

If the `status' statement is omitted the status value `current' is implied.

13.3 The compliance's description Statement

The compliance's `description' statement, which must be present, gets one argument which is used to specify a high-level textual description of this compliance statement.

13.4 The compliance's reference Statement

The compliance's `reference' statement, which need not be present, gets one argument which is used to specify a textual cross-reference to some other document, either another module which defines related compliance statements, or some other document which provides additional information relevant to this compliance statement.

13.5 The compliance's mandatory Statement

The compliance's `mandatory' statement, which need not be present, gets one argument which is used to specify a comma-separated list of one or more groups (The group Statement) of objects and/or notifications enclosed in parenthesis. 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 the `mandatory' statement(s) of the compliance statement(s) of that module.

13.6 The compliance's optional Statement

The compliance's `optional' statement, which need not be present, is repeatedly used to name each group which is conditionally mandatory for compliance to the module. It can also be used to name unconditionally optional groups. A group named in an `optional' statement MUST be absent from the correspondent `mandatory' statement. The `optional' statement gets two arguments: a lower-case group identifier and a statement block that holds detailed compliance information on that group.

Conditionally mandatory groups include those which are mandatory only if a particular protocol is implemented, or only if another group is implemented. The `description' statement specifies the conditions under which the group is conditionally mandatory.

A group which is named in neither a `mandatory' statement nor an `optional' statement, is unconditionally optional for compliance to the module.

See the `optionalStatement' rule of the SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the `optional' statement.

13.6.1 The optional's description Statement

The optional's `description' statement, which must be present, gets one argument which is used to specify a high-level textual description of the conditions under which this group is conditionally mandatory or unconditionally optional.

13.7 The compliance's refine Statement

The compliance's `refine' statement, which need not be present, is repeatedly used to specify each object for which compliance has a refined requirement with respect to the module definition. The object must be present in one of the conformance groups named in the correspondent `mandatory' or `optional' statements. The `refine' statement gets two arguments: a lower-case identifier of a scalar or columnar object and a statement block that holds detailed refinement information on that object.

See the `refineStatement' rule of the SMIng grammar (The SMIng ABNF grammar) for the formal syntax of the `refine' statement.

13.7.1 The refine's type Statement

The refine's `type' statement, which need not be present, gets one argument that is used to provide a refined type for the correspondent object. Type restrictions may be applied by appending subtyping information according to the rules of the base type. See Base Types and Derived Types for SMIng base types and their type restrictions.

Note that if a `type' and a `writetype' statement are both present then this type only applies when instances of the correspondent object are read.

13.7.2 The refine's writetype Statement

The refine's `writetype' statement, which need not be present, gets one argument that is used to provide a refined type for the correspondent object, only when instances of that object are written. Type restrictions may be applied by appending subtyping information according to the rules of the base type. See Base Types and Derived Types for SMIng base types and their type restrictions.

13.7.3 The refine's access Statement

The refine's `access' statement, which need not be present, gets one argument that is used to specify the minimal level of access that the correspondent object must implement in the sense of its original `access' statement. Hence, the refine's `access' statement MUST NOT specify a greater level of access than is specified in the correspondent object definition.

An implementation is compliant if the level of access it provides is greater or equal to the minimal level in the refine's `access' statement and less or equal to the maximal level in the object's `access' statement.

13.7.4 The refine's description Statement

The refine's `description' statement, which must be present, gets one argument which is used to specify a high-level textual description of the refined compliance requirement.

13.8 Usage Example

The compliance statement contained in the SNMPv2-MIB, converted to SMIng:

  compliance snmpBasicCompliance {
    oid             snmpMIBCompliances.2;
    description     
            "The compliance statement for SNMPv2 entities which
             implement the SNMPv2 MIB.";
 
    mandatory       (snmpGroup, snmpSetGroup, systemGroup, 
                     snmpBasicNotificationsGroup);
 
    optional snmpCommunityGroup {
      description   
            "This group is mandatory for SNMPv2 entities which
             support community-based authentication.";
    };
  };


 TOC 

14. SMIng Core Modules

MIB modules, either SMIv1, SMIv2 or SMIng, are built on top of some core definitions. These core definitions are imported from some "well-defined" core modules. In case of SMIng, there are two core modules:

  1. IRTF-NMRG-SMING, which defines a special node, named `zeroDotZero' that may be used by objects of type `ObjectIdentifier' as a null value, and a core set of 18 nodes near the root of the object identifier tree. Only some of those core nodes are significant for the Internet management and have been described in Object Identifier Hierarchy.
  2. IRTF-NMRG-SMING-TYPES, which defines SMIng data types. Regarding to their origin, these types can be divided into two groups: those being ASN.1 application types defined as SMIv2 core types [2] and those being textual conventions in SMIv2 [3]. For use in SMIng, there is no need to care about these differences, though it might be useful in SNMP applications, to know that some types are distinguishable "on the wire" and others are not.
  3. IRTF-NMRG-SMING-EXTENSIONS, which defines proposed SMIng extensions. At this moment, there is only one extension, the `agentcaps' statement. See SMIng Language Extensibility for details on extensions.

14.1 IRTF-NMRG-SMING

module IRTF-NMRG-SMING {

//
// $RCSfile: IRTF-NMRG-SMING,v $
// $Revision: 1.2 $
// $Author: strauss $
// $Date: 2000/02/13 22:11:43 $
//

    organization    "IRTF Network Management Research Group (NMRG),
                     Network Management Group, TU Braunschweig";

    contact         "        Frank Strauss

                     Postal: TU Braunschweig
                             Bueltenweg 74/75
                             38106 Braunschweig
                             Germany

                      Phone: +49 531 391-3266
                      EMail: strauss@ibr.cs.tu-bs.de";

    description     "Core node definitions for SMIng.";

    revision {
        date        "2000-02-13";
        description "SMIng grammar dropped module identity objects.";
    };

    revision {
        date        "1999-05-07";
        description "Initial Revision.";
    };

    node ccitt                          { oid 0;                };

    node   zeroDotZero {
        oid         0.0;
        description "A value used for null identifiers.";
    };

    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;                };

};
            

14.2 IRTF-NMRG-SMING-TYPES

module IRTF-NMRG-SMING-TYPES {

//
// $RCSfile: IRTF-NMRG-SMING-TYPES,v $
// $Revision: 1.3 $
// $Author: strauss $
// $Date: 2000/02/13 22:11:43 $
//

    organization    "IRTF Network Management Research Group (NMRG),
                     Network Management Group, TU Braunschweig";

    contact         "        Frank Strauss

                     Postal: TU Braunschweig
                             Bueltenweg 74/75
                             38106 Braunschweig
                             Germany

                      Phone: +49 531 391-3266
                      EMail: strauss@ibr.cs.tu-bs.de";

    description     "Core type definitions for SMIng.";

    revision {
        date        "2000-02-13";
        description "SMIng grammar dropped module identity objects.";
    };

    revision {
        date        "1999-05-07";
        description "Initial Revision.";
    };

    typedef Gauge32 {
        type        Unsigned32;
        description
           "The Gauge32 type represents a non-negative integer,
            which may increase or decrease, but shall never
            exceed a maximum value, nor fall below a minimum
            value.  The maximum value can not be greater than
            2^32-1 (4294967295 decimal), and the minimum value
            can not be smaller than 0.  The value of a Gauge32
            has its maximum value whenever the information
            being modeled is greater than or equal to its
            maximum value, and has its minimum value whenever
            the information being modeled is smaller than or
            equal to its minimum value.  If the information
            being modeled subsequently decreases below
            (increases above) the maximum (minimum) value, the
            Gauge32 also decreases (increases).  (Note that
            despite of the use of the term `latched' in the
            original definition of this type, it does not
            become `stuck' at its maximum or minimum value.)";
        reference
           "RFC 2578, Sections 2. and 7.1.7.";
    };

    typedef Counter32 {
        type        Unsigned32;
        description
           "The Counter32 type represents a non-negative integer
            which monotonically increases until it reaches a
            maximum value of 2^32-1 (4294967295 decimal), when it
            wraps around and starts increasing again from zero.
               
            Counters have no defined `initial' value, and thus, a
            single value of a Counter has (in general) no
            information content.  Discontinuities in the
            monotonically increasing value normally occur at
            re-initialization of the management system, and at
            other times as specified in the description of an
            object using this type.  If such other times can
            occur, for example, the creation of an object
            instance at times other than re-initialization, then
            a corresponding object should be defined, with an
            appropriate type, to indicate the last discontinuity.
            Examples of appropriate types include: TimeStamp,
            DateAndTime or TimeTicks (other types defined in this
            module).
               
            The value of the access statement for objects with a
            type value of Counter32 should be either `readonly'
            or `notifyonly'.
               
            A default statement should not be used for objects
            with a type value of Counter32.";
        reference
           "RFC 2578, Sections 2. and 7.1.6.";
    };

    typedef Gauge64 {
        type        Unsigned64;
        description
           "The Gauge64 type represents a non-negative integer,
            which may increase or decrease, but shall never
            exceed a maximum value, nor fall below a minimum
            value.  The maximum value can not be greater than
            2^64-1 (18446744073709551615), and the minimum value
            can not be smaller than 0.  The value of a Gauge64
            has its maximum value whenever the information
            being modeled is greater than or equal to its
            maximum value, and has its minimum value whenever
            the information being modeled is smaller than or
            equal to its minimum value.  If the information
            being modeled subsequently decreases below
            (increases above) the maximum (minimum) value, the
            Gauge64 also decreases (increases).  (Note that
            despite of the use of the term `latched' in the
            original definition of this type, it does not
            become `stuck' at its maximum or minimum value.)";
    };

    typedef Counter64 {
        type        Unsigned64;
        description
           "The Counter64 type represents a non-negative integer
            which monotonically increases until it reaches a
            maximum value of 2^64-1 (18446744073709551615), when
            it wraps around and starts increasing again from zero.
               
            Counters have no defined `initial' value, and thus, a
            single value of a Counter has (in general) no
            information content.  Discontinuities in the
            monotonically increasing value normally occur at
            re-initialization of the management system, and at
            other times as specified in the description of an
            object using this type.  If such other times can
            occur, for example, the creation of an object
            instance at times other than re-initialization, then
            a corresponding object should be defined, with an
            appropriate type, to indicate the last discontinuity.
            Examples of appropriate types include: TimeStamp,
            DateAndTime or TimeTicks (other types defined in this
            module).
               
            The value of the access statement for objects with a
            type value of Counter64 should be either `readonly'
            or `notifyonly'.
               
            A default statement should not be used for objects
            with a type value of Counter64.";
        reference
           "RFC 2578, Sections 2. and 7.1.10.";
    };

    typedef Opaque {
        type        OctetString;
        description
           "The Opaque type is provided solely for
            backward-compatibility, and shall not be used for
            newly-defined object types.
                 
            The Opaque type supports the capability to pass
            arbitrary ASN.1 syntax.  A value is encoded using
            the ASN.1 Basic Encoding Rules into a string of
            octets.  This, in turn, is encoded as an
            OctetString, in effect `double-wrapping' the
            original ASN.1 value.
                 
            Note that a conforming implementation need only be
            able to accept and recognize opaquely-encoded data.
            It need not be able to unwrap the data and then
            interpret its contents.
                 
            A requirement on `standard' MIB modules is that no
            object may have a type value of Opaque.";
        reference
           "RFC 2578, Sections 2. and 7.1.9.";
    };

    typedef IpAddress {
        type        OctetString (4);
        status      deprecated;
        description
           "******* THIS TYPE DEFINITION IS DEPRECATED *******

            The IpAddress type represents a 32-bit internet
            IPv4 address.  It is represented as an OctetString
            of length 4, in network byte-order.
                
            Note that the IpAddress type is present for
            historical reasons. IPv4 and IPv6 addresses should
            be represented using the IpAddr type. Generic
            Network addresses should be represented using a
            pair of TDomain and TAddress types (all defined in
            this module).";
        reference
           "RFC 2578, Sections 2. and 7.1.5.";
    };

    typedef TimeTicks {
        type        Unsigned32;
        description
           "The TimeTicks type represents a non-negative
            integer which represents the time, modulo 2^32
            (4294967296 decimal), in hundredths of a second
            between two epochs.  When objects are defined which
            use this type, the description of the object
            identifies both of the reference epochs.
                 
            For example, the TimeStamp type (defined in this
            module) is based on the TimeTicks type.

            With a TimeStamp, the first reference epoch is
            defined as the time when SNMPv2-MIB::sysUpTime was
            zero, and the second reference epoch is defined as
            the current value of sysUpTime.
                 
            The TimeTicks type should not be sub-typed.";
        reference
           "RFC 2578, Sections 2. and 7.1.8.";
    };

    //
    //  The following type definitions are plain
    //  conversions of the textual conventions from
    //  the SNMPv2-TC module (RFC 2579).
    //

    typedef DisplayString {
        type        OctetString (0..255);
        format      "255a";
        description 
        "Represents textual information taken from the NVT ASCII
         character set, as defined in pages 4, 10-11 of RFC 854.
         
         To summarize RFC 854, the NVT ASCII repertoire specifies:
         
          - the use of character codes 0-127 (decimal)
         
          - the graphics characters (32-126) are interpreted as
            US ASCII
         
          - NUL, LF, CR, BEL, BS, HT, VT and FF have the special
            meanings specified in RFC 854
         
          - the other 25 codes have no standard interpretation
         
          - the sequence 'CR LF' means newline
         
          - the sequence 'CR NUL' means carriage-return
         
          - an 'LF' not preceded by a 'CR' means moving to the
            same column on the next line.
         
          - the sequence 'CR x' for any x other than LF or NUL is
            illegal.  (Note that this also means that a string may
            end with either 'CR LF' or 'CR NUL', but not with CR.)
         
         Any object defined using this syntax may not exceed 255
         characters in length.";
    };

    typedef PhysAddress {
        type        OctetString;
        format      "1x:";
        description 
        "Represents media- or physical-level addresses.";
    };

    typedef MacAddress {
        type        OctetString (6);
        format      "1x:";
        description 
        "Represents an 802 MAC address represented in the
         `canonical' order defined by IEEE 802.1a, i.e., as if it
         were transmitted least significant bit first, even though
         802.5 (in contrast to other 802.x protocols) requires MAC
         addresses to be transmitted most significant bit first.";
    };

    typedef TruthValue {
        type        Enumeration (true(1), false(2));
        description 
        "Represents a boolean value.";
    };

    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 syntax 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 ACCESS clause for objects having this
         syntax is either `read-write' or `read-create'.  When an
         instance of a columnar object having this syntax 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
         syntax 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        ObjectIdentifier;
        description 
        "Represents an independently extensible type identification
         value.  It may, for example, indicate a particular sub-tree
         with further MIB definitions, or define a particular type of
         protocol or hardware.";
    };

    typedef InstancePointer {
        type        ObjectIdentifier;
        status      obsolete;
        description 
        "A pointer to either a specific instance of a MIB object or
         a conceptual row of a MIB table in the managed device.  In
         the latter case, by convention, it is the name of the
         particular instance of the first accessible columnar object
         in the conceptual row.
         
         The two uses of this textual convention are replaced by
         VariablePointer and RowPointer, respectively.";
    };

    typedef VariablePointer {
        type        ObjectIdentifier;
        description 
        "A pointer to a specific object instance.  For example,
         sysContact.0 or ifInOctets.3.";
    };

    typedef RowPointer {
        type        ObjectIdentifier;
        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 textual convention is used to manage the
         creation and deletion of conceptual rows, and is used as the
         value of the SYNTAX clause for the status column of a
         conceptual row (as described in Section 7.7.1 of [2].)
         
         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
         status column having a SYNTAX clause value 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) goto 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) the return value can indicate one of the following
         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 the following 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
         
         There are four potential interactions when creating a
         conceptual row: selecting an instance-identifier which is
         not in use; creating the conceptual row; initializing any
         objects for which the agent does not supply a default; and,
         making the conceptual row available for use by the managed
         device.
         
         Interaction 1: Selecting an Instance-Identifier
         
         The algorithm used to select an instance-identifier varies
         for each conceptual row.  In some cases, the instance-
         identifier is semantically significant, e.g., the
         destination address of a route, and a management station
         selects the instance-identifier according to the semantics.
         
         In other cases, the instance-identifier is used solely to
         distinguish conceptual rows, and a management station
         without specific knowledge of the conceptual row might
         examine the instances present in order to determine an
         unused instance-identifier.  (This approach may be used, but
         it is often highly sub-optimal; however, it is also a
         questionable practice for a naive management station to
         attempt conceptual row creation.)
         
         Alternately, the MIB module which defines the conceptual row
         might provide one or more objects which provide assistance
         in determining an unused instance-identifier.  For example,
         if the conceptual row is indexed by an integer-value, then
         an object having an integer-valued SYNTAX clause might be
         defined for such a purpose, allowing a management station to
         issue a management protocol retrieval operation.  In order
         to avoid unnecessary collisions between competing management
         stations, `adjacent' retrievals of this object should be
         different.
         
         
         Finally, the management station could select a pseudo-random
         number to use as the index.  In the event that this index
         was already in use and an inconsistentValue was returned in
         response to the management protocol set operation, the
         management station should simply select a new pseudo-random
         number and retry the operation.
         
         A MIB designer should choose between the two latter
         algorithms based on the size of the table (and therefore the
         efficiency of each algorithm).  For tables in which 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 small numbers 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 determines if it wishes to create and
         activate the conceptual row in one transaction or in a
         negotiated set of interactions.
         
         Interaction 2a: Creating and Activating the Conceptual Row
         
         The management station must first determine the column
         requirements, i.e., it must determine those columns for
         which it must or must not provide values.  Depending on the
         complexity of the table and the management station's
         knowledge of the agent's capabilities, this determination
         can be made locally by the management station.  Alternately,
         the management station issues a management protocol get
         operation to examine all columns in the conceptual row that
         it wishes to create.  In response, for each column, there
         are three possible outcomes:
         
             - a value is returned, indicating that some other
             management station has already created this conceptual
             row.  We return to interaction 1.
         
         
             - the exception `noSuchInstance' is returned,
             indicating that the agent implements the object-type
             associated with this column, and that this column in at
             least one conceptual row would be accessible in the MIB
             view used by the retrieval were it to exist. For those
             columns to which the agent provides read-create access,
             the `noSuchInstance' exception tells the management
             station that it should supply a value for this column
             when the conceptual row is to be created.
         
             - the exception `noSuchObject' is returned, indicating
             that the agent does not implement the object-type
             associated with this column or that there is no
             conceptual row for which this column would be
             accessible in the MIB view used by the retrieval.  As
             such, the management station can not issue any
             management protocol set operations to create an
             instance of this column.
         
         Once the column requirements have been determined, a
         management protocol set operation is accordingly issued.
         This operation also sets the new instance of the status
         column to `createAndGo'.
         
         When the agent processes the set operation, it verifies that
         it has sufficient information to make the conceptual row
         available for use by the managed device.  The information
         available to the agent is provided by two sources: the
         management protocol set operation which creates the
         conceptual row, and, implementation-specific defaults
         supplied by the agent (note that an agent must provide
         implementation-specific defaults for at least those objects
         which it implements as read-only).  If there is sufficient
         information available, then the conceptual row is created, a
         `noError' response is returned, the status column is set to
         `active', and no further interactions are necessary (i.e.,
         interactions 3 and 4 are skipped).  If there is insufficient
         information, then the conceptual row is not created, and the
         set operation fails with an error of `inconsistentValue'.
         On this error, the management station can issue a management
         protocol retrieval operation to determine if this was
         because it failed to specify a value for a required column,
         or, because the selected instance of the status column
         already existed.  In the latter case, we return to
         interaction 1.  In the former case, the management station
         
         
         can re-issue the set operation with the additional
         information, or begin interaction 2 again using
         `createAndWait' in order to negotiate creation of the
         conceptual row.
         
                                 NOTE WELL
         
             Regardless of the method used to determine the column
             requirements, it is possible that the management
             station might deem a column necessary when, in fact,
             the agent will not allow that particular columnar
             instance to be created or written.  In this case, the
             management protocol set operation will fail with an
             error such as `noCreation' or `notWritable'.  In this
             case, the management station decides whether it needs
             to be able to set a value for that particular columnar
             instance.  If not, the management station re-issues the
             management protocol set operation, but without setting
             a value for that particular columnar instance;
             otherwise, the management station aborts the row
             creation algorithm.
         
         
         Interaction 2b: Negotiating the Creation of the Conceptual
         Row
         
         The management station issues a management protocol set
         operation which sets the desired instance of the status
         column to `createAndWait'.  If the agent is unwilling to
         process a request of this sort, the set operation fails with
         an error of `wrongValue'.  (As a consequence, such an agent
         must be prepared to accept a single management protocol set
         operation, i.e., interaction 2a above, containing all of the
         columns indicated by its column requirements.) Otherwise,
         the conceptual row is created, a `noError' response is
         returned, and the status column is immediately set to either
         `notInService' or `notReady', depending on whether it has
         sufficient information to make the conceptual row available
         for use by the managed device.  If there is sufficient
         information available, then the status column is set to
         `notInService'; otherwise, if there is insufficient
         information, then the status column is set to `notReady'.
         Regardless, we proceed to interaction 3.
         
         Interaction 3: Initializing non-defaulted Objects
         
         The management station must now determine the column
         requirements.  It issues a management protocol get operation
         to examine all columns in the created conceptual row.  In
         the response, for each column, there are three possible
         outcomes:
         
             - a value is returned, indicating that the agent
             implements the object-type associated with this column
             and had sufficient information to provide a value.  For
             those columns to which the agent provides read-create
             access (and for which the agent allows their values to
             be changed after their creation), a value return tells
             the management station that it may issue additional
             management protocol set operations, if it desires, in
             order to change the value associated with this column.
         
         
             - the exception `noSuchInstance' is returned,
             indicating that the agent implements the object-type
             associated with this column, and that this column in at
             least one conceptual row would be accessible in the MIB
             view used by the retrieval were it to exist. However,
             the agent does not have sufficient 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 those columns to which the agent
             provides read-create access, the `noSuchInstance'
             exception tells the management station that it must
             issue additional management protocol set operations, in
             order to provide a value associated with this column.
         
             - the exception `noSuchObject' is returned, indicating
             that the agent does not implement the object-type
             associated with this column or that there is no
             conceptual row for which this column would be
             accessible in the MIB view used by the retrieval.  As
             such, the management station can not issue any
             management protocol set operations to create an
             instance of this column.
         
         If the value associated with the status column is
         `notReady', then the management station must first deal with
         all `noSuchInstance' columns, if any.  Having done so, the
         value of the status column becomes `notInService', and we
         proceed to interaction 4.
         
         Interaction 4: Making the Conceptual Row Available
         
         Once the management station is satisfied with the values
         associated with the columns of the conceptual row, it issues
         a management protocol set operation to set the status column
         to `active'.  If the agent has sufficient information to
         make the conceptual row available for use by the managed
         device, the management protocol set operation succeeds (a
         `noError' response is returned).  Otherwise, the management
         protocol set operation fails with an error of
         `inconsistentValue'.
         
         
                                 NOTE WELL
         
             A conceptual row having a status column with value
             `notInService' or `notReady' is unavailable to the
             managed device.  As such, it is possible for the
             managed device to create its own instances during the
             time between the management protocol set operation
             which sets the status column to `createAndWait' and the
             management protocol set operation which sets the status
             column to `active'.  In this case, when the management
             protocol set operation is issued to set the status
             column to `active', the values held in the agent
             supersede those used by the managed device.
         
         If the management station is prevented from setting the
         status column to `active' (e.g., due to management station
         or network failure) the conceptual row will be left in the
         `notInService' or `notReady' state, consuming resources
         indefinitely.  The agent must detect conceptual rows that
         have been in either state for an abnormally long period of
         time and remove them.  It is the responsibility of the
         DESCRIPTION clause of the status column to indicate what an
         abnormally long period of time would be.  This period of
         time should be long enough to allow for human response time
         (including `think time') between the creation of the
         conceptual row and the setting of the status to `active'.
         In the absence of such information in the DESCRIPTION
         clause,
         it is suggested that this period be approximately 5 minutes
         in length.  This removal action applies not only to newly-
         created rows, but also to previously active rows which are
         set to, and left in, the notInService state for a prolonged
         period exceeding that which is considered normal for such a
         conceptual row.
         
         
                         Conceptual Row Suspension
         
         When a conceptual row is `active', the management station
         may issue a management protocol set operation which sets the
         instance of the status column to `notInService'.  If the
         agent is unwilling to do so, the set operation fails with an
         error of `wrongValue' or `inconsistentValue'.
         Otherwise, the conceptual row is taken out of service, and a
         `noError' response is returned.  It is the responsibility of
         the DESCRIPTION clause of the status column to indicate
         under what circumstances the status column should be taken
         out of service (e.g., in order for the value of some other
         column of the same conceptual row to be modified).
         
                          Conceptual Row Deletion
         
         For deletion of conceptual rows, a management protocol set
         operation is issued which sets the instance of the status
         column to `destroy'.  This request may be made regardless of
         the current value of the status column (e.g., it is possible
         to delete conceptual rows which are either `notReady',
         `notInService' or `active'.) If the operation succeeds, then
         all instances associated with the conceptual row are
         immediately removed.";
    };

    typedef TimeStamp {
        type        TimeTicks;
        description 
        "The value of the sysUpTime object at which a specific
         occurrence happened.  The specific occurrence must be
         defined in the description of any object defined using this
         type.  When the specific occurrence occurred prior to the
         last time sysUpTime was zero, then the TimeStamp value is
         zero.  Note that this requires all TimeStamp values to be
         reset to zero when the value of sysUpTime reaches 497+ days
         and wraps around to zero.";
    };

    typedef TimeInterval {
        type        Integer32 (0..2147483647);
        description 
        "A period of time, measured in units of 0.01 seconds.";
    };

    typedef DateAndTime {
        type        OctetString (8 | 11);
        format      "2d-1d-1d,1d:1d:1d.1d,1a1d:1d";
        description 
        "A date-time specification.
         
         field  octets  contents                  range
         -----  ------  --------                  -----
          1      1-2   year*                     0..65536
          2       3    month                     1..12
          3       4    day                       1..31
          4       5    hour                      0..23
          5       6    minutes                   0..59
          6       7    seconds                   0..60
                       (use 60 for leap-second)
          7       8    deci-seconds              0..9
          8       9    direction from UTC        '+' / '-'
          9      10    hours from UTC*           0..13
         10      11    minutes from UTC          0..59
         
         * Notes:
         - the value of year is in big-endian encoding
         - daylight saving time in New Zealand is +13
         
         For example, Tuesday May 26, 1992 at 1:30:15 PM EDT would be
         displayed as:
         
                         1992-5-26,13:30:15.0,-4:0
         
         Note that if only local time is known, then timezone
         information (fields 8-10) is not present.";
    };

    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        ObjectIdentifier;
        description 
        "Denotes a kind of transport service.
         
         Some possible values, such as snmpUDPDomain, are defined in
         'Transport Mappings for Version 2 of the Simple Network
         Management Protocol (SNMPv2)'.";
    };

    typedef TAddress {
        type        OctetString (1..255);
        description 
        "Denotes a transport service address.
         
         For snmpUDPDomain, a TAddress is 6 octets long, the initial
         4 octets containing the IP-address in network-byte order and
         the last 2 containing the UDP port in network-byte order.
         Cosult 'Transport Mappings for Version 2 of the Simple
         Network Management Protocol (SNMPv2)' for further
         information on snmpUDPDomain.";
    };

};
            

14.3 IRTF-NMRG-SMING-EXTENSIONS

module IRTF-NMRG-SMING-EXTENSIONS {

//
// $RCSfile: IRTF-NMRG-SMING-EXTENSIONS,v $
// $Revision: 1.3 $
// $Author: strauss $
// $Date: 2000/02/13 22:11:43 $
//

    organization    "IRTF Network Management Research Group (NMRG),
                     Network Management Group, TU Braunschweig";

    contact         "        Frank Strauss

                     Postal: TU Braunschweig
                             Bueltenweg 74/75
                             38106 Braunschweig
                             Germany

                      Phone: +49 531 391-3266
                      EMail: strauss@ibr.cs.tu-bs.de";

    description     "Core extension definitions for SMIng.";

    revision {
        date        "2000-02-13";
        description "SMIng grammar dropped module identity objects.";
    };

    revision {
        date        "1999-05-07";
        description "Initial Revision.";
    };

    extension agentcaps {
        status      current;
        description     
              "The agentcaps extension statement is used to describe
               an agent's deviation from the compliance statements
               of the modules it implements. It is designed to be
               compatible with the SMIv2 AGENT-CAPABILITIES macro.

               The agentcaps extension statement should only be used
               in the statement body of a module that does not
               contain any other type or node definitions that do not
               correspond to an agent implementation.";
        reference     
              "RFC 2580, Section 6 describes the SMIv2
               compatible AGENT-CAPABILITIES macro.";
        abnf
              "agentcapsStatement = 'agentcaps' sep lcIdentifier
                                    optsep '{' stmtsep
                                      oidStatement stmtsep
                                      releaseStatement stmtsep
                                      *1(statusStatement stmtsep)
                                      descriptionStatement stmtsep
                                      *1(referenceStatement stmtsep)
                                      *(includesStatement stmtsep)
                                    '}' optsep ';'
  
               includesStatement  = 'includes' sep qlcIdentifier
                                    optsep '{' stmtsep
                                      *(variationStatement stmtsep)
                                    '}' optsep ';'
  
               variationStatement = 'variation' sep qlcIdentifier 
                                    optsep '{' stmtsep
                                      typeStatement stmtsep
                                      writetypeStatement stmtsep
                                      accessStatement stmtsep
                                      createStatement stmtsep
                                    '}' optsep ';'             
               ";
    };

};
            


 TOC 

15. Extending a Module

As experience is gained with a module, it may be desirable to revise that module. However, changes are not allowed if they have any potential to cause interoperability problems between an implementation using an original specification and an implementation using an updated specification(s).

For any change, some statements near the top of the module MUST be updated to include information about the revision: specifically, a new `revision' statement (The module's revision Statement) must be included in front of the `revision' statements. Furthermore, any necessary changes MUST be applied to other statements, including the `organization' and `contact' statements (The module's organization Statement, The module's contact Statement).

Note that any definition contained in a module is available to be imported by any other module, and is referenced in an `import' statement via the module name. Thus, a module name MUST NOT be changed. Specifically, the module name (e.g., `FIZBIN-MIB' in the example of Usage Example) MUST NOT be changed when revising a module (except to correct typographical errors), and definitions MUST NOT be moved from one module to another.

Also note, that obsolete definitions MUST NOT be removed from modules since their descriptors may still be referenced by other modules, and the object identifiers used to name them MUST never be re-assigned.

A definition may be revised in any of the following ways:

Otherwise, if the semantics of any previous definition are changed (i.e., if a non-editorial change is made to any definition other than those specifically allowed above), then the `oid' statement value associated with that object MUST also be changed.

Note that changing the identifier associated with an existing object is considered a semantic change, as these strings may be used in an `import' statement.



 TOC 

16. SMIng Language Extensibility

While SMIng has a well defined set of statements (The module Statement through The compliance Statement) that are used to specify those aspects of management information commonly regarded as necessary, there may be further information, people wish to express. To describe additional information informally in description statements has the disadvantage, that this information cannot be parsed by any program.

SMIng allows modules to include statements that are unknown to a parser but fulfill some core grammar rules (Statements and Arguments). Furthermore, additional statements may be defined by the `extension' statement (The extension Statement). Extensions can be used in the local module or in other modules, that import the extension. This has some advantages:

The only formal effect of an extension statement definition is to declare its existence and its status, and optionally its ABNF grammar. All additional aspects SHOULD be described in the `description' statement:

Some possible extension applications might be:



 TOC 

17. Module Conversions

17.1 Converting SMIv2 to SMIng

Conversions of SMIv2 modules to SMIng are feasible. The only SMIv2 construct that cannot be mapped to an SMIng statement is the AGENT-CAPABILITIES macro. However, this can be mapped to the `agentcaps' extension. All other constructs and types are directly mappable without loss of information.

Detailed mapping information is subject to a future document.

17.2 Converting SMIng to SMIv2

SMIng is more liberal in some aspects to ensure a more consistent information model and a short grammar with less exceptions. This leads to a limited backwards convertability to SMIv2 of different kinds of identifiers, groups, type definition hierarchies, octet string length limitations, and object identifier values (those with a single sub-identifier). Some other information gets lost when being converted to SMIv2: some occurences of references, units, formats, default values, table indexing information, and table row creation information.

Detailed mapping information is subject to a future document.

17.3 SMIv1

Conversions between SMIv1 and SMIng are not covered by this document. Anyhow, conversions between SMIv1 and SMIv2 are subject to SMIv2 and partly described in [14]. Conversions between SMIv2 and SMIng are covered in the sections above.

In few words, conversion from SMIv1 to SMIng is not possible in some cases and without some additional information. Conversion from SMIng to SMIv1 is possible if 64 bit types and floating point data types are not used and if identifiers conform to the SMIv1 restrictions.



 TOC 

18. Security Considerations

This document defines a language with which to write and read descriptions of management information. The language itself has no security impact on the Internet.



 TOC 

19. Acknowledgements

This document is originated as a central part of a master's thesis at the Technical University of Braunschweig, under the guidance of Juergen Schoenwaelder.

Since SMIng represents a successor of SMIv2, a huge amount of paragraphs and phrases are taken from the SMIv2 specifications [2], [3], [4] written by Jeff Case, Keith McCloghrie, David Perkins, Marshall T. Rose, Juergen Schoenwaelder, and Steven L. Waldbusser.

Finally, Marshall T. Rose's work on an XML framework for RFC authors [15] made the writing of an Internet standards document much more feasible.

Thanks to these people and the authors of these documents.



 TOC 

References

[1] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", RFC 2119, BCP 14, March 1997.
[2] McCloghrie, K., Perkins, D., Schoenwaelder, J., Case, J., Rose, M., Waldbusser, S., "Structure of Management Information Version 2 (SMIv2)", RFC 2578, STD 58, April 1999.
[3] McCloghrie, K., Perkins, D., Schoenwaelder, J., Case, J., Rose, M., Waldbusser, S., "Textual Conventions for SMIv2", RFC 2579, STD 59, April 1999.
[4] McCloghrie, K., Perkins, D., Schoenwaelder, J., Case, J., Rose, M., Waldbusser, S., "Conformance Statements for SMIv2", RFC 2580, STD 60, April 1999.
[5] Rose, M., McCloghrie, K., "Structure and Identification of Management Information for TCP/IP-based Internets", RFC 1155, STD 16, May 1990.
[6] Rose, M., McCloghrie, K., "Concise MIB Definitions", RFC 1212, STD 16, March 1991.
[7] Rose, M., "A Convention for Defining Traps for use with the SNMP", RFC 1215, March 1991.
[8] Crocker, D., Overell, P., "Augmented BNF for Syntax Specifications: ABNF", RFC 2234, November 1997.
[9] International Organization for Standardization, "Specification of Abstract Syntax Notation One (ASN.1)", International Standard 8824, December 1987.
[10] Harrington, D., Presuhn, R., Wijnen, B., "An Architecture for Describing SNMP Management Frameworks", RFC 2271, January 1999.
[11] Institute of Electrical and Electronics Engineers, "IEEE Standard for Binary Floating-Point Arithmetic", ANSI/IEEE Standard 754-1985, August 1985.
[12] Yergeau, F., "UTF-8, a transformation format of ISO 10646", RFC 2279, January 1998.
[13] Case, J., McCloghrie, K., Rose, M., Waldbusser, S., "Management Information Base for Version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1907, January 1996.
[14] Wijnen, B., Levi, D., "V2ToV1 - Mapping SNMPv2 onto SNMPv1 within a bi-lingual SNMP agent", RFC 2089, January 1997.
[15] Rose, M., "Writing I-Ds and RFCs using XML", RFC 2629, June 1999.


 TOC 

Author's Address

  Frank Strauss
  TU Braunschweig
  Bueltenweg 74/75
  38106 Braunschweig
  Germany
Phone:  +49 531 391-3266
EMail:  strauss@ibr.cs.tu-bs.de
URI:  http://www.ibr.cs.tu-bs.de/


 TOC 

Appendix A. The SMIng ABNF grammar

The SMIng grammar conforms to the Augmented Backus-Naur Form (ABNF)[8], with one exception: For readability, keywords are represented as quoted strings, although ABNF would declare these strings to be case-insensitive. Anyhow, SMIng keyword are meant to be case-sensitive.

;;
;; sming.abnf -- SMIng grammar in ABNF notation (RFC 2234).
;;
;; @(#) $Id: sming.abnf,v 1.5 2000/02/13 22:17:56 strauss Exp $
;;
;; Copyright (C) The Internet Society (1999). All Rights Reserved.
;;

smingFile               = optsep *(moduleStatement optsep)

;;
;; Statement rules.
;;

moduleStatement         = moduleKeyword sep ucIdentifier optsep "{" stmtsep
                              *(importStatement stmtsep)
                              organizationStatement stmtsep
                              contactStatement stmtsep
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                              1*(revisionStatement stmtsep)
                              *1(identityStatement stmtsep)
                              *(extensionStatement stmtsep)
                              *(typedefStatement stmtsep)
                              *(anyObjectStatement stmtsep)
                              *(notificationStatement stmtsep)
                              *(groupStatement stmtsep)
                              *(complianceStatement stmtsep)
                          "}" optsep ";"

extensionStatement      = extensionKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                              *1(abnfStatement stmtsep)
                          "}" optsep ";"

typedefStatement        = typedefKeyword sep ucIdentifier optsep
                              "{" stmtsep
                              typedefTypeStatement stmtsep
                              *1(defaultStatement stmtsep)
                              *1(formatStatement stmtsep)
                              *1(unitsStatement stmtsep)
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                          "}" optsep ";"

anyObjectStatement      = nodeStatement /
                          scalarStatement /
                          tableStatement

nodeStatement           = nodeKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              oidStatement stmtsep
                              *1(statusStatement stmtsep)
                              *1(descriptionStatement stmtsep)
                              *1(referenceStatement stmtsep)
                          "}" optsep ";"

scalarStatement         = scalarKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              oidStatement stmtsep
                              typeStatement stmtsep
                              accessStatement stmtsep
                              *1(defaultStatement stmtsep)
                              *1(formatStatement stmtsep)
                              *1(unitsStatement stmtsep)
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                          "}" optsep ";"

tableStatement          = tableKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              oidStatement stmtsep
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                              rowStatement stmtsep
                          "}" optsep ";"

rowStatement            = rowKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              oidStatement stmtsep
                              anyIndexStatement stmtsep
                              *1(createStatement stmtsep)
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                              1*(columnStatement stmtsep)
                          "}" optsep ";"

columnStatement         = columnKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              oidStatement stmtsep
                              typeStatement stmtsep
                              accessStatement stmtsep
                              *1(defaultStatement stmtsep)
                              *1(formatStatement stmtsep)
                              *1(unitsStatement stmtsep)
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                          "}" optsep ";"

notificationStatement   = notificationKeyword sep lcIdentifier
                              optsep "{" stmtsep
                              oidStatement stmtsep
                              *1(objectsStatement stmtsep)
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                          "}" optsep ";"

groupStatement          = groupKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              oidStatement stmtsep
                              membersStatement stmtsep
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                          "}" optsep ";"

complianceStatement     = complianceKeyword sep lcIdentifier optsep
                              "{" stmtsep
                              oidStatement stmtsep
                              *1(statusStatement stmtsep)
                              descriptionStatement stmtsep
                              *1(referenceStatement stmtsep)
                              *1(mandatoryStatement stmtsep)
                              *(optionalStatement stmtsep)
                              *(refineStatement stmtsep)
                          "}" optsep ";"

importStatement         = importKeyword sep ucIdentifier optsep
                              "(" optsep
                              identifierList optsep
                          ")" optsep ";"

revisionStatement       = revisionKeyword optsep "{" stmtsep
                              dateStatement stmtsep
                              descriptionStatement stmtsep
                          "}" optsep ";"

identityStatement       = identityKeyword sep lcIdentifier optsep ";"

typedefTypeStatement    = typeKeyword sep refinedBaseType optsep ";"

typeStatement           = typeKeyword sep
                              (refinedBaseType / refinedType)
                              optsep ";"

writetypeStatement      = writetypeKeyword sep
                              (refinedBaseType / refinedType)
                              optsep ";"

anyIndexStatement       = indexStatement /
                          augmentsStatement /
                          reordersStatement /
                          sparseStatement /
                          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 ";"

sparseStatement         = sparseKeyword sep qlcIdentifier optsep ";"

expandsStatement        = expandsKeyword sep qlcIdentifier
                              *1(sep impliedKeyword)
                              optsep "(" optsep
                              qlcIdentifierList optsep ")"
                              optsep ";"

createStatement         = createKeyword optsep ";"

oidStatement            = oidKeyword sep objectIdentifier optsep ";"

dateStatement           = dateKeyword sep date optsep ";"

organizationStatement   = organizationKeyword sep text optsep ";"

contactStatement        = contactKeyword sep text optsep ";"

formatStatement         = formatKeyword sep format optsep ";"

unitsStatement          = unitsKeyword sep units optsep ";"

statusStatement         = statusKeyword sep status optsep ";"

accessStatement         = accessKeyword sep access optsep ";"

defaultStatement        = defaultKeyword sep anyValue optsep ";"

descriptionStatement    = descriptionKeyword sep text optsep ";"

referenceStatement      = referenceKeyword sep text optsep ";"

abnfStatement           = abnfKeyword sep text optsep ";"

membersStatement        = membersKeyword optsep "(" optsep
                              qlcIdentifierList optsep
                              ")" optsep ";"

objectsStatement        = objectsKeyword 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 ";"

;;
;;
;;

refinedBaseType         = OctetStringKeyword *1(optsep numberSpec) /
                          ObjectIdentifierKeyword /
                          Integer32Keyword *1(optsep numberSpec) /
                          Unsigned32Keyword *1(optsep numberSpec) /
                          Integer64Keyword *1(optsep numberSpec) /
                          Unsigned64Keyword *1(optsep numberSpec) /
                          Float32Keyword *1(optsep floatSpec) /
                          Float64Keyword *1(optsep floatSpec) /
                          Float128Keyword *1(optsep floatSpec) /
                          EnumerationKeyword optsep namedNumberSpec /
// TODO: inserted optsep, do also in parser grammar!
                          BitsKeyword optsep namedNumberSpec 
// TODO: inserted optsep, do also in parser grammar!

refinedType             = qucIdentifier *1(optsep anySpec)

anySpec                 = numberSpec / floatSpec

numberSpec              = "(" optsep numberElement
                              *furtherNumberElement
                              optsep ")"

furtherNumberElement    = optsep "|" optsep numberElement

numberElement           = signedNumber *1numberUpperLimit

numberUpperLimit        = optsep ".." optsep signedNumber

floatSpec               = "(" optsep floatElement
                              *furtherFloatElement
                              optsep ")"

furtherFloatElement     = optsep "|" optsep floatElement

floatElement            = floatValue *1floatUpperLimit

floatUpperLimit         = optsep ".." optsep floatValue

namedNumberSpec         = "(" optsep namedNumberList optsep ")"

namedNumberList         = namedNumberItem
                              *(optsep "," optsep namedNumberItem)
                              *1(optsep ",")

namedNumberItem         = lcIdentifier optsep "(" optsep number
                              optsep ")"

identifierList          = identifier
                              *(optsep "," optsep identifier)
                              *1(optsep ",")

qIdentifierList         = qIdentifier
                              *(optsep "," optsep qIdentifier)
                              *1(optsep ",")

qlcIdentifierList       = qlcIdentifier 
                              *(optsep "," optsep qlcIdentifier)
                              *1(optsep ",")

bitsValue               = "(" optsep bitsList optsep ")"

bitsList                = *1(lcIdentifier 
                              *(optsep "," optsep lcIdentifier))
                              *1(optsep ",")

;;
;; Other basic rules.
;;

identifier              = ucIdentifier / lcIdentifier

qIdentifier             = qucIdentifier / qlcIdentifier

ucIdentifier            = ucAlpha *63(ALPHA / DIGIT / "-")

qucIdentifier           = *1(ucIdentifier "::") ucIdentifier

lcIdentifier            = lcAlpha *63(ALPHA / DIGIT / "-")

qlcIdentifier           = *1(ucIdentifier "::") lcIdentifier

text                    = textSegment *(optsep textSegment)

textSegment             = DQUOTE *textAtom DQUOTE

textAtom                = textVChar / HTAB / SP / lineBreak

date                    = DQUOTE 4DIGIT "-" 2DIGIT "-" 2DIGIT
                              *1(" " 2DIGIT ":" 2DIGIT)
                              DQUOTE
                          ; always in UTC

format                  = textSegment

units                   = textSegment

anyValue                = bitsValue /
                          negativeNumber /
                          hexadecimalNumber /
                          floatValue /
                          text /
                          objectIdentifier
                          ; Note: `objectIdentifer' includes the
                          ; syntax of enumeration labels and postive
                          ; numbers. They are not named literally to
                          ; avoid reduce/reduce conflicts when
                          ; building LR parsers based on this   
                          ; grammar.

status                  = currentKeyword /
                          deprecatedKeyword /
                          obsoleteKeyword

access                  = noaccessKeyword /
                          notifyonlyKeyword /
                          readonlyKeyword /
                          readwriteKeyword

objectIdentifier        = (qlcIdentifier / subid) *127("." subid)

subid                   = decimalNumber

number                  = hexadecimalNumber / decimalNumber

negativeNumber          = "-" decimalNumber

signedNumber            = number / negativeNumber

decimalNumber           = "0" / (nonZeroDigit *DIGIT)

zeroDecimalNumber       = 1*DIGIT

hexadecimalNumber       = "0x" 1*(HEXDIG HEXDIG)

floatValue              = neginfKeyword / 
                          posinfKeyword /
                          snanKeyword / 
                          qnanKeyword /
                          signedNumber "." zeroDecimalNumber
                              *1("E" ("+"/"-") zeroDecimalNumber)

;;
;; Rules to skip unknown statements
;; with arbitrary arguments and blocks.
;;

unknownStatement        = unknownKeyword optsep *unknownArgument
                              optsep ";"

unknownArgument         = ("(" optsep unknownList optsep ")") /
                          ("{" optsep *unknownStatement optsep "}") /
                          qucIdentifier / 
                          anyValue /
                          anySpec

unknownList             = namedNumberList / 
                          qIdentifierList

unknownKeyword          = lcIdentifier

;;
;; Keyword rules.
;;
;; Typically, keywords are represented by tokens returned from the
;; lexical analyzer.  Note, that the lexer has to be stateful to
;; distinguish keywords from identifiers depending on the context
;; position in the input stream.
;;
;; Also note, that these keyword definitions are represented in
;; cleartext for readability, while SMIng keywords are meant to be
;; case-sensitive, although ABNF makes quoted strings like these to
;; be case-insensitive.
;;

;; Statement keywords.

moduleKeyword           = "module"
importKeyword           = "import"
revisionKeyword         = "revision"
oidKeyword              = "oid"
dateKeyword             = "date"
organizationKeyword     = "organization"
contactKeyword          = "contact"
descriptionKeyword      = "description"
referenceKeyword        = "reference"
identityKeyword         = "identity"
extensionKeyword        = "extension"
typedefKeyword          = "typedef"
typeKeyword             = "type"
writetypeKeyword        = "writetype"
nodeKeyword             = "node"
scalarKeyword           = "scalar"
tableKeyword            = "table"
columnKeyword           = "column"
rowKeyword              = "row"
notificationKeyword     = "notification"
groupKeyword            = "group"
complianceKeyword       = "compliance"
formatKeyword           = "format"
unitsKeyword            = "units"
statusKeyword           = "status"
accessKeyword           = "access"
defaultKeyword          = "default"
impliedKeyword          = "implied"
indexKeyword            = "index"
augmentsKeyword         = "augments"
reordersKeyword         = "reorders"
sparseKeyword           = "sparse"
expandsKeyword          = "expands"
createKeyword           = "create"
membersKeyword          = "members"
objectsKeyword          = "objects"
mandatoryKeyword        = "mandatory"
optionalKeyword         = "optional"
refineKeyword           = "refine"
abnfKeyword             = "abnf"

;; Base type keywords.

OctetStringKeyword      = "OctetString"
ObjectIdentifierKeyword = "ObjectIdentifier"
Integer32Keyword        = "Integer32"
Unsigned32Keyword       = "Unsigned32"
Integer64Keyword        = "Integer64"
Unsigned64Keyword       = "Unsigned64"
Float32Keyword          = "Float32"
Float64Keyword          = "Float64"
Float128Keyword         = "Float128"
BitsKeyword             = "Bits"
EnumerationKeyword      = "Enumeration"

;; Status keyword.

currentKeyword          = "current"
deprecatedKeyword       = "deprecated"
obsoleteKeyword         = "obsolete"

;; Access keywords.

noaccessKeyword         = "noaccess"
notifyonlyKeyword       = "notifyonly"
readonlyKeyword         = "readonly"
readwriteKeyword        = "readwrite"

;; Special floating point values' keywords.

neginfKeyword           = "neginf"
posinfKeyword           = "posinf"
snanKeyword             = "snan"
qnanKeyword             = "qnan"

;;
;; Some low level rules.
;; These tokens are typically skipped by the lexical analyzer.
;;

sep                     = 1*(comment / lineBreak / WSP)
                          ; unconditional separator

optsep                  = *(comment / lineBreak / WSP)

stmtsep                 = *(comment /
                            lineBreak /
                            WSP /
                            unknownStatement)

comment                 = "//" *(WSP / VCHAR) lineBreak 

lineBreak               = CRLF / LF

;;
;; Encoding specific rules.
;;

textVChar               = %x21 / %x23-7E
                          ; any VCHAR except DQUOTE

ucAlpha                 = %x41-5A

lcAlpha                 = %x61-7A

nonZeroDigit            = %x31-39

;;
;; RFC 2234 core rules.
;;

ALPHA          =  %x41-5A / %x61-7A
                       ; A-Z / a-z

CR             =  %x0D
                       ; carriage return

CRLF           =  CR LF
                       ; Internet standard newline

DIGIT          =  %x30-39
                       ; 0-9

DQUOTE         =  %x22
                       ; " (Double Quote)

HEXDIG         =  DIGIT / "A" / "B" / "C" / "D" / "E" / "F"

HTAB           =  %x09
                       ; horizontal tab

LF             =  %x0A
                       ; linefeed

SP             =  %x20
                       ; space

VCHAR          =  %x21-7E
                       ; visible (printing) characters

WSP            =  SP / HTAB
                       ; white space

;;
;; EOF
;;
          


 TOC 

Appendix B. Glossary

columnar object:
An object in a table row that may have zero, one or more object instances. Instances are identified by using the values of `indexing objects' as `instance identifier'.
extension:
The SMIng `extension' statement can be used to define new statements. Extensions can express annotations to existent management information, agent capabilities known from SMIv2, or arbitrary other information. See SMIng Language Extensibility for details.
identifier:
The name of any definition, either a module, type, node, scalar object, table, row, columnar object, notification, group, compliance, a named number of an enumeration or bits type or any construct defined by an SMIng extension. Every identifier starts with an upper-case or lower-case character, followed by letters, digits and hyphens, but without consecutive or trailing hyphens. The length of an identifier MUST NOT exceed 64 characters. Note that SMIng keywords may be used as identifiers, though it's NOT RECOMMENDED. See also Identifiers.
indexing objects:
A Table may contain multiple instances of single columnar objects. That is, there may be multiple rows. The table's `indexing objects' are used to unambiguously distinguish the rows of a table. A special encoding of their values represents the columns' instance-identifier, and thus identifies the row.
instance-identifier:
That part of an object identifier value, that is used to unambiguously identify an instance of an object. For scalar objects, the instance-identifier is `0'. For columnar objects, the instance-identifier is built from the values of the `indexing objects'. See also Scalar and Columnar Objects' Instances.
module:
A module is the container of inter-related management information, either managed objects or other definitions like type definitions or annotations. A module has to conform the SMIng grammar and semantics described by this document. A module represents a namespace in which local definitions are available and external definitions have to be imported.
named number:
Values of `Enumeration' types (Enumeration) and single elements of `Bits' (Bits) types are integer numbers, each associated with an identifers. Those number-identifier pairs are called `named numbers'.
object:
A leaf definition in the object identifier tree, that represents a class of object instances. Objects are exactly those definitions declared by the SMIng keywords `scalar' or `column'.
object identifier:
Management information is organized in a tree of nodes. Each node is unambiguously identified by an `object identifier', that consists of a sequence of integer numbers (`sub-identifiers') which represent the path of nodes from the root to the addressed node in the tree. See also The Information Model.
row:
The kind of node used to group columnar objects of a table. Some significant information on table indexing and information used for row creation and deletion is associated with a table's row definition.
scalar object:
An object that has zero or one object instance.
sub-identifier:
A single component of an object identifier. There are at most 128 sub-identifiers in an object identifier value and each sub-identifier has a maximum value of 2^32-1 (4294967295).
table:
The kind of node used to group management information that is organized in a sequence of rows.



 TOC 

Full Copyright Statement