RFC 1902

Structure of Management Information for Version 2 of the Simple Network Management Protocol (SNMPv2)

๐Ÿ“… published January 1996, from ietf

RFC 1902: Structure of Management Information for Version 2 of SNMPv2 ๐ŸŽ€

okay bestie, this is the one where the SNMPv2 Working Group wrote the rulebook for how management data gets described. ๐Ÿ’… It's a Standards Track document, so it's an actual Internet standard and not just a casual suggestion. It's dated January 1996, and it obsoletes RFC 1442. Its authors are J. Case (SNMP Research, Inc.), K. McCloghrie (Cisco Systems, Inc.), M. Rose (Dover Beach Consulting, Inc.), and S. Waldbusser (International Network Services). The title block doesn't list anything it updates, so that's it for the lineup. โœจ


Status of this Memo ๐Ÿ“œ

This document specifies an Internet standards track protocol for the Internet community, and requests discussion and suggestions for improvements. Please refer to the current edition of the "Internet Official Protocol Standards" (STD 1) for the standardization state and status of this protocol. Distribution of this memo is unlimited.


1. Introduction โœจ

okay so a management system is basically a little squad ๐Ÿซถ with a few parts. You've got several (potentially many) nodes, and each one has a processing entity called an agent that can get at management instrumentation. You also need at least one management station, plus a management protocol to carry management information between the agents and the stations. The protocol runs under an administrative framework that defines authentication, authorization, access control, and privacy policies. Main character energy, honestly. ๐Ÿฆ‹

Management stations run management applications that monitor and control managed elements. Managed elements are things like hosts, routers, terminal servers, and so on, and they get monitored and controlled through access to their management information. ๐ŸŒˆ

Management information is seen as a collection of managed objects that live in a virtual information store called the Management Information Base (MIB). Collections of related objects get defined in MIB modules. These modules are written in an adapted subset of OSI's Abstract Syntax Notation One (ASN.1) [1]. The whole point of this document, the Structure of Management Information (SMI), is to define that adapted subset and assign a set of associated administrative values. ๐Ÿ’–

The SMI is split into three parts: module definitions, object definitions, and notification definitions. ๐Ÿ“

(1) Module definitions are used when describing information modules. An ASN.1 macro, MODULE-IDENTITY, is used to concisely convey the semantics of an information module.

(2) Object definitions are used when describing managed objects. An ASN.1 macro, OBJECT-TYPE, is used to concisely convey the syntax and semantics of a managed object.

(3) Notification definitions are used when describing unsolicited transmissions of management information. An ASN.1 macro, NOTIFICATION-TYPE, is used to concisely convey the syntax and semantics of a notification.

1.1. A Note on Terminology ๐Ÿ’…

okay quick vocab check ๐Ÿงš for the exposition, the original Internet-standard Network Management Framework, as described in RFCs 1155 (STD 16), 1157 (STD 15), and 1212 (STD 16), gets called the SNMP version 1 framework (SNMPv1). The current framework is called the SNMP version 2 framework (SNMPv2). Now you know which one everyone's talking about. ๐Ÿ˜ญ


2. Definitions ๐Ÿฆ‹

Here's the full SMI module, copied exactly as written, because the details are everything. ๐Ÿ™ˆ

SNMPv2-SMI DEFINITIONS ::= BEGIN


-- the path to the root

org            OBJECT IDENTIFIER ::= { iso 3 }
dod            OBJECT IDENTIFIER ::= { org 6 }
internet       OBJECT IDENTIFIER ::= { dod 1 }

directory      OBJECT IDENTIFIER ::= { internet 1 }

mgmt           OBJECT IDENTIFIER ::= { internet 2 }
mib-2          OBJECT IDENTIFIER ::= { mgmt 1 }
transmission   OBJECT IDENTIFIER ::= { mib-2 10 }

experimental   OBJECT IDENTIFIER ::= { internet 3 }

private        OBJECT IDENTIFIER ::= { internet 4 }
enterprises    OBJECT IDENTIFIER ::= { private 1 }

security       OBJECT IDENTIFIER ::= { internet 5 }
snmpV2         OBJECT IDENTIFIER ::= { internet 6 }

-- transport domains
snmpDomains    OBJECT IDENTIFIER ::= { snmpV2 1 }

-- transport proxies
snmpProxys     OBJECT IDENTIFIER ::= { snmpV2 2 }

-- module identities
snmpModules    OBJECT IDENTIFIER ::= { snmpV2 3 }


-- definitions for information modules

MODULE-IDENTITY MACRO ::=
BEGIN
    TYPE NOTATION ::=
                  "LAST-UPDATED" value(Update UTCTime)
                  "ORGANIZATION" Text
                  "CONTACT-INFO" Text
                  "DESCRIPTION" Text
                  RevisionPart

    VALUE NOTATION ::=
                  value(VALUE OBJECT IDENTIFIER)

    RevisionPart ::=
                  Revisions
                | empty
    Revisions ::=
                  Revision
                | Revisions Revision
    Revision ::=
                  "REVISION" value(Update UTCTime)
                  "DESCRIPTION" Text

    -- uses the NVT ASCII character set
    Text ::= """" string """"
END


OBJECT-IDENTITY MACRO ::=
BEGIN
    TYPE NOTATION ::=
                  "STATUS" Status
                  "DESCRIPTION" Text
                  ReferPart

    VALUE NOTATION ::=
                  value(VALUE OBJECT IDENTIFIER)

    Status ::=
                  "current"
                | "deprecated"
                | "obsolete"

    ReferPart ::=
                "REFERENCE" Text
              | empty

    Text ::= """" string """"
END


-- names of objects

ObjectName ::=
    OBJECT IDENTIFIER

NotificationName ::=
    OBJECT IDENTIFIER

-- syntax of objects

ObjectSyntax ::=
    CHOICE {
        simple
            SimpleSyntax,

          -- note that SEQUENCEs for conceptual tables and
          -- rows are not mentioned here...

        application-wide
            ApplicationSyntax
    }


-- built-in ASN.1 types

SimpleSyntax ::=
    CHOICE {
        -- INTEGERs with a more restrictive range
        -- may also be used
        integer-value               -- includes Integer32
            INTEGER (-2147483648..2147483647),

        -- OCTET STRINGs with a more restrictive size
        -- may also be used
        string-value
            OCTET STRING (SIZE (0..65535)),

        objectID-value
            OBJECT IDENTIFIER
    }


-- indistinguishable from INTEGER, but never needs more than
-- 32-bits for a two's complement representation
Integer32 ::=
    [UNIVERSAL 2]
        IMPLICIT INTEGER (-2147483648..2147483647)


-- application-wide types

ApplicationSyntax ::=
    CHOICE {
        ipAddress-value
            IpAddress,

        counter-value
            Counter32,

        timeticks-value
            TimeTicks,

        arbitrary-value
            Opaque,

        big-counter-value
            Counter64,

        unsigned-integer-value  -- includes Gauge32
            Unsigned32
    }

-- in network-byte order
-- (this is a tagged type for historical reasons)
IpAddress ::=
    [APPLICATION 0]
        IMPLICIT OCTET STRING (SIZE (4))

-- this wraps
Counter32 ::=

    [APPLICATION 1]
        IMPLICIT INTEGER (0..4294967295)

-- this doesn't wrap
Gauge32 ::=
    [APPLICATION 2]
        IMPLICIT INTEGER (0..4294967295)

-- an unsigned 32-bit quantity
-- indistinguishable from Gauge32
Unsigned32 ::=
    [APPLICATION 2]
        IMPLICIT INTEGER (0..4294967295)

-- hundredths of seconds since an epoch
TimeTicks ::=
    [APPLICATION 3]
        IMPLICIT INTEGER (0..4294967295)

-- for backward-compatibility only
Opaque ::=
    [APPLICATION 4]
        IMPLICIT OCTET STRING

-- for counters that wrap in less than one hour with only 32 bits
Counter64 ::=
    [APPLICATION 6]
        IMPLICIT INTEGER (0..18446744073709551615)


-- definition for objects

OBJECT-TYPE MACRO ::=
BEGIN
    TYPE NOTATION ::=
                  "SYNTAX" Syntax
                  UnitsPart
                  "MAX-ACCESS" Access
                  "STATUS" Status
                  "DESCRIPTION" Text
                  ReferPart
                  IndexPart
                  DefValPart

    VALUE NOTATION ::=
                  value(VALUE ObjectName)

    Syntax ::=

                  type(ObjectSyntax)
                | "BITS" "{" Kibbles "}"
    Kibbles ::=
                  Kibble
                | Kibbles "," Kibble
    Kibble ::=
                 identifier "(" nonNegativeNumber ")"

    UnitsPart ::=
                  "UNITS" Text
                | empty

    Access ::=
                  "not-accessible"
                | "accessible-for-notify"
                | "read-only"
                | "read-write"
                | "read-create"

    Status ::=
                  "current"
                | "deprecated"
                | "obsolete"

    ReferPart ::=
                  "REFERENCE" Text
                | empty

    IndexPart ::=
                  "INDEX"    "{" IndexTypes "}"
                | "AUGMENTS" "{" Entry      "}"
                | empty
    IndexTypes ::=
                  IndexType
                | IndexTypes "," IndexType
    IndexType ::=
                  "IMPLIED" Index
                | Index
    Index ::=
                    -- use the SYNTAX value of the
                    -- correspondent OBJECT-TYPE invocation
                  value(Indexobject ObjectName)
    Entry ::=
                    -- use the INDEX value of the
                    -- correspondent OBJECT-TYPE invocation
                  value(Entryobject ObjectName)

    DefValPart ::=

                  "DEFVAL" "{" value(Defval Syntax) "}"
                | empty

    -- uses the NVT ASCII character set
    Text ::= """" string """"
END


-- definitions for notifications

NOTIFICATION-TYPE MACRO ::=
BEGIN
    TYPE NOTATION ::=
                  ObjectsPart
                  "STATUS" Status
                  "DESCRIPTION" Text
                  ReferPart

    VALUE NOTATION ::=
                  value(VALUE NotificationName)

    ObjectsPart ::=
                  "OBJECTS" "{" Objects "}"
                | empty
    Objects ::=
                  Object
                | Objects "," Object
    Object ::=
                  value(Name ObjectName)

    Status ::=
                  "current"
                | "deprecated"
                | "obsolete"

    ReferPart ::=
                "REFERENCE" Text
              | empty

    -- uses the NVT ASCII character set
    Text ::= """" string """"
END

-- definitions of administrative identifiers

zeroDotZero    OBJECT-IDENTITY
    STATUS     current
    DESCRIPTION

            "A value used for null identifiers."
    ::= { 0 0 }

END

3. Information Modules ๐ŸŒธ

okay so an "information module" is an ASN.1 module that defines information about network management. โœจ

The SMI tells you how to use a subset of ASN.1 to define an information module. On top of that, "standard" information modules get extra restrictions. It is strongly recommended that "enterprise-specific" information modules also follow these restrictions. ๐Ÿ’œ

Typically there are three kinds of information modules: ๐ŸŒˆ

(1) MIB modules, which contain definitions of inter-related managed objects, and make use of the OBJECT-TYPE and NOTIFICATION-TYPE macros;

(2) compliance statements for MIB modules, which make use of the MODULE-COMPLIANCE and OBJECT-GROUP macros [2]; and,

  • (3) capability statements for agent implementations which make use of the AGENT-CAPABILITIES macros [2].

okay so this classification is NOT a strict box system, bestie ๐Ÿ’… A "standard" information module will normally include managed object definitions AND a compliance statement, and an "enterprise-specific" one might include managed object definitions AND a capability statement. The only hard no is that a "standard" information module may not contain capability statements ๐Ÿ™…โ€โ™€๏ธ

The ASN.1 constructs you're allowed to use in SNMPv2 information modules are: the IMPORTS clause, value definitions for OBJECT IDENTIFIERs, type definitions for SEQUENCEs (with restrictions), ASN.1 type assignments of the restricted ASN.1 types allowed in SNMPv2, and instances of ASN.1 macros defined in this document and in other documents [2, 3] of the SNMPv2 framework. Additional ASN.1 macros may not be defined in SNMPv2 information modules. No inventing your own macros, periodt โœจ

The names of all standard information modules MUST be unique, but different versions of the same information module SHOULD have the same name ๐ŸŒธ Enterprise devs are encouraged to pick names that are unlikely to collide with standard or other enterprise information modules, so nobody's module gets mixed up with someone else's ๐Ÿซถ Also, an information module may not use the ASN.1 construct of placing an object identifier value between the module name and the "DEFINITIONS" keyword ๐Ÿ™ˆ

All information modules start with exactly one invocation of the MODULE-IDENTITY macro. This is the bit that gives contact info and revision history so people can tell versions of the same module apart ๐Ÿ“– This invocation MUST appear immediately after any IMPORTs statements, no exceptions bestie ๐Ÿ‘‘

3.1. Macro Invocation ๐Ÿฆ‹

Within an information module, each macro invocation looks like this:

  <descriptor> <macro> <clauses> ::= <value>

where <descriptor> is an ASN.1 identifier, <macro> names the macro being invoked, and <clauses> and <value> depend on how that macro is defined. (Heads up: this definition of a descriptor applies to all macros defined in this memo and in [2], so it's a whole family thing ๐Ÿ’•)

For the purposes of this spec, an ASN.1 identifier is made of one or more letters or digits, and its initial character MUST be a lower-case letter. Hyphens are NOT allowed by this spec, even though hyphen is allowed by [1]. Why? Because this restriction lets arithmetic expressions in languages that use the minus sign reference these descriptors without any ambiguity ๐Ÿง  Galaxy brain move โœจ

For all descriptors in an information module, the descriptor SHALL be unique and mnemonic, and SHALL NOT exceed 64 characters in length. Descriptors longer than 32 characters are NOT RECOMMENDED, though ๐Ÿ™ƒ The whole point is a common language humans can use when talking about the module, and it makes simple table mappings for user interfaces way easier ๐Ÿ’–

The set of descriptors defined in all "standard" information modules SHALL be unique ๐Ÿ”ฅ

Finally, by convention: if the descriptor refers to an object whose SYNTAX clause value is either Counter32 or Counter64, then the descriptor used for that object SHOULD denote plurality ๐Ÿ“

3.1.1. Textual Clauses ๐ŸŽ€

Some clauses in a macro invocation take a textual value (the DESCRIPTION clause is the classic example). To keep the ASN.1 syntax happy, the entire value of these clauses MUST be enclosed in double quotation marks. That means the value cannot itself contain double quotation marks, although it MAY be multi-line ๐ŸŒˆ

3.2. IMPORTing Symbols ๐Ÿ“ฆ

To reference an external object, you MUST use the IMPORTS statement to identify both the descriptor and the module it's defined in. The module gets identified by its ASN.1 module name ๐Ÿ’œ

Heads up on enterprise-specific modules: referencing symbols from them (like a descriptor) can cause collisions ๐Ÿ˜ฌ So if different objects with the same descriptor get IMPORTed, the ambiguity is resolved by prefixing the descriptor with the information module name and a dot, like this:

"module.descriptor"

(All descriptors MUST be unique within any information module, btw ๐Ÿ™Œ)

Of course you can use this notation even when there's no collision when IMPORTing symbols. Extra clarity never hurt anyone ๐Ÿ’…

Finally, the IMPORTS statement may not be used to import an ASN.1 named type that corresponds to either the SEQUENCE or SEQUENCE OF type ๐Ÿšซ

3.3. Exporting Symbols ๐Ÿฆข

The ASN.1 EXPORTS statement is not allowed in SNMPv2 information modules. Everything defined in an information module is automatically exported, so you don't have to do anything extra โœจ

3.4. ASN.1 Comments ๐Ÿ’ฌ

Comments in ASN.1 start with a pair of adjacent hyphens and end at the next pair of adjacent hyphens or at the end of the line, whichever comes first ๐ŸŒธ

3.5. OBJECT IDENTIFIER values ๐Ÿ”ข

An OBJECT IDENTIFIER value is an ordered list of non-negative numbers. For the SNMPv2 framework, each number in the list is called a sub-identifier. There are at most 128 sub-identifiers in a value, and each sub-identifier has a maximum value of 2^32-1 (4294967295 decimal) ๐Ÿ˜ญ Every OBJECT IDENTIFIER value has at least two sub-identifiers, and the first one MUST be one of these well-known names:

  Value   Name
    0     ccitt
    1     iso
    2     joint-iso-ccitt

4. Naming Hierarchy ๐ŸŒณ

The root of the subtree administered by the Internet Assigned Numbers Authority (IANA) for the Internet is:

  internet       OBJECT IDENTIFIER ::= { iso 3 6 1 }

So the Internet subtree of OBJECT IDENTIFIERs starts with the prefix:

  1.3.6.1.

A few branches underneath this subtree are used for network management:

  mgmt           OBJECT IDENTIFIER ::= { internet 2 }
  experimental   OBJECT IDENTIFIER ::= { internet 3 }
  private        OBJECT IDENTIFIER ::= { internet 4 }
  enterprises    OBJECT IDENTIFIER ::= { private 1 }

The SMI doesn't prohibit defining objects in other parts of the object tree, though ๐Ÿ‘€

The mgmt(2) subtree is used to identify "standard" objects ๐Ÿ†

The experimental(3) subtree is used to identify objects being designed by IETF working groups ๐Ÿงช If an information module produced by a working group becomes a "standard" information module, then right at the very beginning of its entry onto the Internet standards track, its objects get moved under the mgmt(2) subtree. Glow-up arc unlocked ๐Ÿฆ‹

The private(4) subtree is used to identify objects defined unilaterally ๐Ÿ•ถ๏ธ The enterprises(1) subtree under private is used, among other things, to let networking subsystem providers register models of their products ๐Ÿข

5. Mapping of the MODULE-IDENTITY macro ๐Ÿชช

The MODULE-IDENTITY macro gives contact info and revision history for each information module. It MUST appear exactly once in every information module. It SHOULD be noted that the expansion of the MODULE-IDENTITY macro conceptually happens during implementation and NOT at run-time โฐ

Note that when you reference an information module in an IMPORTS clause or in clauses of SNMPv2 macros, you do NOT use the 'descriptor' of a MODULE-IDENTITY macro. Instead, you reference the information module by specifying its module name ๐Ÿ“›

5.1. Mapping of the LAST-UPDATED clause ๐Ÿ—“๏ธ

The LAST-UPDATED clause MUST be present. It contains the date and time this information module was last edited, represented in UTC Time format (see Appendix B) โณ

5.2. Mapping of the ORGANIZATION clause ๐Ÿ›๏ธ

The ORGANIZATION clause MUST be present. It contains a textual description of the organization under whose auspices this information module was developed ๐Ÿค

5.3. Mapping of the CONTACT-INFO clause โ˜Ž๏ธ

The CONTACT-INFO clause MUST be present. It contains the name, postal address, telephone number, and electronic mail address of the person to whom technical queries about this information module should be sent ๐Ÿ“ฎ

5.4. Mapping of the DESCRIPTION clause ๐Ÿ“

The DESCRIPTION clause MUST be present. It contains a high-level textual description of the contents of this information module ๐Ÿญ

5.5. Mapping of the REVISION clause ๐Ÿ”

The REVISION clause need not be present. It's used repeatedly to describe the revisions (including the initial version) made to this information module, in reverse chronological order (most recent first) ๐Ÿ•ฐ๏ธ Each instance of this clause contains the date and time of the revision, represented in UTC Time format (see Appendix B) ๐Ÿ“…

5.5.1. Mapping of the DESCRIPTION sub-clause ๐Ÿ–Š๏ธ

The DESCRIPTION clause MUST be present for each REVISION clause. It contains a high-level textual description of the revision identified in that REVISION clause ๐Ÿ’Œ

5.6. Mapping of the MODULE-IDENTITY value ๐Ÿ†”

The value of an invocation of the MODULE-IDENTITY macro is an OBJECT IDENTIFIER. Because of that, this value MAY be authoritatively used when specifying an OBJECT IDENTIFIER value to refer to the information module containing the invocation ๐ŸŽฏ

5.7. Usage Example ๐Ÿง

Let's look at how a skeletal MIB module might be constructed, e.g.,

FIZBIN-MIB DEFINITIONS ::= BEGIN

IMPORTS
    MODULE-IDENTITY, OBJECT-TYPE, experimental
        FROM SNMPv2-SMI;


fizbin MODULE-IDENTITY
    LAST-UPDATED "9505241811Z"
    ORGANIZATION "IETF SNMPv2 Working Group"
    CONTACT-INFO
            "        Marshall T. Rose

             Postal: Dover Beach Consulting, Inc.
                     420 Whisman Court
                     Mountain View, CA  94043-2186
                     US

                Tel: +1 415 968 1052
                Fax: +1 415 968 2510

             E-mail: mrose@dbc.mtview.ca.us"
    DESCRIPTION
            "The MIB module for entities implementing the xxxx
            protocol."
    REVISION      "9505241811Z"
    DESCRIPTION
            "The latest version of this MIB module."
    REVISION      "9210070433Z"
    DESCRIPTION
            "The initial version of this MIB module."
-- contact IANA for actual number
    ::= { experimental xx }


END

6. Mapping of the OBJECT-IDENTITY macro ๐Ÿช„

The OBJECT-IDENTITY macro defines information about an OBJECT IDENTIFIER assignment. All administrative OBJECT IDENTIFIER assignments that define a type identification value (see AutonomousType, a textual convention defined in [3]) SHOULD be defined via the OBJECT-IDENTITY macro โœจ It SHOULD be noted that the expansion of the OBJECT-IDENTITY macro conceptually happens during implementation and NOT at run-time ๐Ÿ•

6.1. Mapping of the STATUS clause ๐Ÿšฆ

The STATUS clause MUST be present. It indicates whether this definition is current or historic ๐Ÿ“œ

The values "current" and "obsolete" are self-explanatory ๐Ÿ’โ€โ™€๏ธ The "deprecated" value indicates that the definition is obsolete, but that an implementor MAY wish to support it to foster interoperability with older implementations ๐Ÿค๐Ÿ’–

6.2. Mapping of the DESCRIPTION clause ๐Ÿ“

The DESCRIPTION clause MUST be present. It contains a textual description of the object assignment ๐ŸŒท

6.3. Mapping of the REFERENCE clause ๐Ÿ”—

The REFERENCE clause need not be present. It contains a textual cross-reference to an object assignment defined in some other information module ๐Ÿ“š

6.4. Mapping of the OBJECT-IDENTITY value ๐Ÿงฉ

The value of an invocation of the OBJECT-IDENTITY macro is an OBJECT IDENTIFIER ๐Ÿ’Ž

6.5. Usage Example ๐ŸŒŸ

Let's look at how an OBJECT IDENTIFIER assignment might be made, e.g.,

fizbin69 OBJECT-IDENTITY
    STATUS  current
    DESCRIPTION
            "The authoritative identity of the Fizbin 69 chipset."
    ::= { fizbinChipSets 1 }

7. Mapping of the OBJECT-TYPE macro โœจ

Okay so the OBJECT-TYPE macro is how we define a type of managed object ๐ŸŽ€. Bestie, the expansion of this macro happens conceptually during implementation, and it's NOT something that happens at run-time ๐Ÿ™ˆ.

For leaf objects that aren't columnar objects (i.e., not contained within a conceptual table), you find an instance by appending a sub-identifier of zero to the name of that object. Otherwise, the INDEX clause of the conceptual row object superior to a columnar object defines the instance identification info ๐Ÿ’….

7.1. Mapping of the SYNTAX clause ๐Ÿงš

The SYNTAX clause is the one that MUST be present ๐Ÿ’–. It defines the abstract data structure that matches that object. The data structure MUST be one of the following: a base type, the BITS construct, or a textual convention. (SEQUENCE OF and SEQUENCE are also possible for conceptual tables, see section 7.1.12.) The base types are the ones defined in the ObjectSyntax CHOICE, and a textual convention is a newly-defined type that's a sub-type of a base type [3] ๐Ÿฆ‹.

An extended subset of the full ASN.1 sub-typing capabilities is allowed, depending on the underlying ASN.1 type. Any restriction on size, range, enumerations or repertoire that's specified in this clause is the maximal level of support that "makes protocol sense" ๐Ÿ’œ. Restrictions on sub-typing are specified in detail in Section 9 and Appendix C of this memo, so go check those out ๐Ÿ‘‘.

The semantics of ObjectSyntax are described next ๐ŸŒธ.

7.1.1. Integer32 and INTEGER

The Integer32 type represents integer-valued info between -2^31 and 2^31-1 inclusive (-2147483648 to 2147483647 decimal). This type is indistinguishable from the INTEGER type. Both the INTEGER and Integer32 types may be sub-typed to be more constrained than the Integer32 type ๐Ÿ“.

The INTEGER type can also represent integer-valued info as named-number enumerations. In that case, only the named-numbers that are enumerated may be present as a value. Also, even though it is RECOMMENDED that enumerated values start at 1 and be numbered contiguously, any valid value for Integer32 is allowed for an enumerated value, and enumerated values needn't be contiguously assigned ๐Ÿค“.

Finally, a label for a named-number enumeration MUST consist of one or more letters or digits (no hyphens), up to a maximum of 64 characters, and the initial character MUST be a lower-case letter. (However, labels longer than 32 characters are NOT RECOMMENDED.) ๐ŸŽ€

7.1.2. OCTET STRING

The OCTET STRING type represents arbitrary binary or textual data ๐Ÿฆ‹. There's no SMI-specified size limit for this type, but MIB designers SHOULD realize that there may be implementation and interoperability limitations for sizes in excess of 255 octets ๐Ÿ˜ญ.

7.1.3. OBJECT IDENTIFIER

The OBJECT IDENTIFIER type represents administratively assigned names ๐Ÿ“›. Any instance of this type may have at most 128 sub-identifiers. Further, each sub-identifier MUST NOT exceed the value 2^32-1 (4294967295 decimal) ๐Ÿ’….

7.1.4. The BITS construct

The BITS construct represents an enumeration of named bits ๐ŸŒˆ. This collection is assigned non-negative, contiguous values, starting at zero. Only the named-bits that are enumerated may be present in a value. (So enumerations MUST be assigned to consecutive bits. However, see Section 9 for refinements of an object with this syntax ๐Ÿซถ.)

There's no SMI-specified limitation on the number of enumerations (and so on the length of a value), but MIB designers SHOULD realize that there may be implementation and interoperability limitations for sizes in excess of 128 bits โœจ.

Finally, a label for a named-number enumeration MUST consist of one or more letters or digits (no hyphens), up to a maximum of 64 characters, and the initial character MUST be a lower-case letter. (However, labels longer than 32 characters are NOT RECOMMENDED.) ๐Ÿ’–

7.1.5. IpAddress

The IpAddress type represents a 32-bit internet address ๐ŸŒธ. It's represented as an OCTET STRING of length 4, in network byte-order ๐Ÿ”ฅ.

Note that the IpAddress type is a tagged type for historical reasons ๐Ÿ™ˆ. Network addresses SHOULD be represented using an invocation of the TEXTUAL-CONVENTION macro [3] ๐Ÿ’….

7.1.6. Counter32

The Counter32 type represents a non-negative integer that monotonically increases until it reaches a maximum value of 2^32-1 (4294967295 decimal). Then it wraps around and starts increasing again from zero ๐Ÿ”„.

Counters have no defined "initial" value, so a single value of a Counter has (in general) no information content ๐Ÿคทโ€โ™€๏ธ. Discontinuities in the monotonically increasing value normally happen at re-initialization of the management system, and at other times as specified in the description of an object-type that uses this ASN.1 type. If such other times can occur (for example, creating an object instance at times other than re-initialization), then a corresponding object SHOULD be defined with a SYNTAX clause value of TimeStamp (a textual convention defined in [3]) that indicates the time of the last discontinuity ๐Ÿ’œ.

The MAX-ACCESS clause for objects with a SYNTAX clause value of Counter32 is either "read-only" or "accessible-for-notify" ๐Ÿ‘‘. A DEFVAL clause is not allowed for objects with a SYNTAX clause value of Counter32 ๐Ÿšซ.

7.1.7. Gauge32

The Gauge32 type represents a non-negative integer that may increase or decrease, but SHALL never exceed a maximum value ๐Ÿ“ˆ. The maximum value can not be greater than 2^32-1 (4294967295 decimal). The value of a Gauge has its maximum value whenever the info being modeled is greater than or equal to that maximum value. If the info being modeled later decreases below the maximum value, the Gauge also decreases ๐ŸŽข.

7.1.8. TimeTicks

The TimeTicks type represents a non-negative integer that represents the time, modulo 2^32 (4294967296 decimal), in hundredths of a second between two epochs โฐ. When objects are defined that use this ASN.1 type, the description of the object identifies both of the reference epochs ๐Ÿง .

For example, [3] defines the TimeStamp textual convention, which is based on the TimeTicks type. With a TimeStamp, the first reference epoch is defined as the time when sysUpTime [5] was zero, and the second reference epoch is defined as the current value of sysUpTime ๐Ÿ•ฐ๏ธ.

The TimeTicks type may not be sub-typed ๐Ÿ™…โ€โ™€๏ธ.

7.1.9. Opaque

The Opaque type is provided solely for backward-compatibility, and it SHALL NOT be used for newly-defined object types ๐Ÿšซ. It's the type that lets you pass arbitrary ASN.1 syntax. A value is encoded using the ASN.1 Basic Encoding Rules [4] into a string of octets. That then gets encoded as an OCTET STRING, which is in effect "double-wrapping" the original ASN.1 value ๐ŸŽ.

Note that a conforming implementation only needs to be able to accept and recognize opaquely-encoded data. It doesn't need to be able to unwrap the data and then interpret its contents ๐Ÿซ .

A requirement on "standard" MIB modules is that no object may have a SYNTAX clause value of Opaque โœ‹.

7.1.10. Counter64

The Counter64 type represents a non-negative integer that monotonically increases until it reaches a maximum value of 2^64-1 (18446744073709551615 decimal). Then it wraps around and starts increasing again from zero ๐ŸŒŠ.

Counters have no defined "initial" value, so a single value of a Counter has (in general) no information content. Discontinuities in the monotonically increasing value normally happen at re-initialization of the management system, and at other times as specified in the description of an object-type that uses this ASN.1 type. If such other times can occur (for example, creating an object instance at times other than re-initialization), then a corresponding object SHOULD be defined with a SYNTAX clause value of TimeStamp (a textual convention defined in [3]) that indicates the time of the last discontinuity ๐Ÿญ.

The MAX-ACCESS clause for objects with a SYNTAX clause value of Counter64 is either "read-only" or "accessible-for-notify" ๐Ÿ’ซ.

A requirement on "standard" MIB modules is that the Counter64 type MAY be used only if the information being modeled would wrap in less than one hour if the Counter32 type was used instead โณ.

A DEFVAL clause is not allowed for objects with a SYNTAX clause value of Counter64 ๐Ÿšซ.

7.1.11. Unsigned32

The Unsigned32 type represents integer-valued information between 0 and 2^32-1 inclusive (0 to 4294967295 decimal) ๐Ÿฉท.

7.1.12. Conceptual Tables

Management operations apply exclusively to scalar objects ๐ŸŽฏ. But it's sometimes convenient for developers of management apps to impose an imaginary, tabular structure on an ordered collection of objects within the MIB ๐Ÿ“Š. Each conceptual table contains zero or more rows, and each row may contain one or more scalar objects, called columnar objects. This idea is formalized by using the OBJECT-TYPE macro to define both an object that corresponds to a table and an object that corresponds to a row in that table ๐Ÿงฉ. A conceptual table has SYNTAX of the form:

SEQUENCE OF <EntryType>

where <EntryType> refers to the SEQUENCE type of its subordinate conceptual row. A conceptual row has SYNTAX of the form:

<EntryType>

where <EntryType> is a SEQUENCE type defined as follows:

<EntryType> ::= SEQUENCE { <type1>, ... , <typeN> }

where there is one <type> for each subordinate object, and each <type> is of the form:

<descriptor> <syntax>

where <descriptor> is the descriptor naming a subordinate object, and <syntax> has the value of that subordinate object's SYNTAX clause, normally with the sub-typing info left out. Also, these ASN.1 types are always present (the DEFAULT and OPTIONAL clauses are disallowed in the SEQUENCE definition) ๐Ÿ™…. The MAX-ACCESS clause for conceptual tables and rows is "not-accessible" ๐Ÿ”’.

7.1.12.1. Creation and Deletion of Conceptual Rows

For newly-defined conceptual rows that allow the creation of new object instances and/or the deletion of existing object instances, there SHOULD be one columnar object with a SYNTAX clause value of RowStatus (a textual convention defined in [3]) and a MAX-ACCESS clause value of read-create. By convention, this is termed the status column for the conceptual row ๐Ÿšฆ.

7.2. Mapping of the UNITS clause ๐Ÿ“

This UNITS clause, which need not be present, contains a textual definition of the units associated with that object ๐Ÿ’•.

7.3. Mapping of the MAX-ACCESS clause ๐ŸŽ€

okay so the MAX-ACCESS clause, which MUST be present, is all about whether it makes "protocol sense" to read, write and/or create 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 read-write means read and write access make "protocol sense", but create does not. The value read-create means read, write and create access all make "protocol sense" โœจ The value not-accessible is for an auxiliary object (see Section 7.7). The value accessible-for-notify is for an object that's only reachable through a notification (e.g., snmpTrapOID [5]) ๐Ÿ””

These values are ordered, from least to greatest: not-accessible, accessible-for-notify, read-only, read-write, read-create ๐Ÿ“Š

Here's the tea ๐Ÿซ– if any columnar object in a conceptual row has read-create as its maximal level of access, then no other columnar object of the same conceptual row MAY have a maximal access of read-write. (Note that read-create is a superset of read-write.) main character energy, literally ๐Ÿ‘‘

7.4. Mapping of the STATUS clause ๐ŸŒธ

The STATUS clause, which MUST be present, tells you whether a definition is current or historic ๐Ÿ•ฐ๏ธ

"current" and "obsolete" are self-explanatory, bestie ๐Ÿ™ˆ the "deprecated" value means the definition is obsolete, but an implementor MAY wish to support that object to foster interoperability with older implementations ๐Ÿซถ

7.5. Mapping of the DESCRIPTION clause ๐Ÿ“

The DESCRIPTION clause, which MUST be present, is the textual definition of the object. It gives all the semantic definitions needed for implementation, and it SHOULD embody any information that would otherwise be communicated in ASN.1 commentary annotations attached to the object ๐Ÿ’œ

7.6. Mapping of the REFERENCE clause ๐Ÿ”—

The REFERENCE clause, which need not be present, is a textual cross-reference to an object defined in some other information module. This is super useful when de-osifying a MIB module produced by some other organization ๐Ÿงš

7.7. Mapping of the INDEX clause ๐Ÿ—‚๏ธ

The INDEX clause, which MUST be present if that object corresponds to a conceptual row (unless an AUGMENTS clause is present instead), and MUST be absent otherwise, gives instance identification information for the columnar objects subordinate to that object ๐ŸŽ€

The instance identification information in an INDEX clause MUST specify object(s) such that the value(s) of those object(s) will unambiguously distinguish a conceptual row. The syntax of those objects shows how to form the instance-identifier ๐Ÿ”

  1. integer-valued: a single sub-identifier taking the integer value (this works only for non-negative integers);
  2. string-valued, fixed-length strings (or variable-length preceded by the IMPLIED keyword): n sub-identifiers, where n is the length of the string (each octet of the string is encoded in a separate sub-identifier);
  3. string-valued, variable-length strings (not preceded by the IMPLIED keyword): n+1 sub-identifiers, where n is the length of the string (the first sub-identifier is n itself, and following this, each octet of the string is encoded in a separate sub-identifier);
  4. object identifier-valued (when preceded by the IMPLIED keyword): n sub-identifiers, where n is the number of sub-identifiers in the value (each sub-identifier of the value is copied into a separate sub-identifier);
  5. object identifier-valued (when not preceded by the IMPLIED keyword): n+1 sub-identifiers, where n is the number of sub-identifiers in the value (the first sub-identifier is n itself, and following this, each sub-identifier in the value is copied);
  6. IpAddress-valued: 4 sub-identifiers, in the familiar a.b.c.d notation.

Note that the IMPLIED keyword can only be present for an object with a variable-length syntax (e.g., variable-length strings or object identifier-valued objects). Further, the IMPLIED keyword can only be associated with the last object in the INDEX clause. Finally, the IMPLIED keyword may not be used on a variable-length string object if that string might have a value of zero-length. โš ๏ธ

Instances identified by integer-valued objects SHOULD be numbered starting from one (i.e., not from zero). Using zero as a value for an integer-valued index object SHOULD be avoided, except in special cases ๐Ÿ™ƒ

Objects that are both specified in the INDEX clause of a conceptual row and also columnar objects of the same conceptual row are called auxiliary objects. The MAX-ACCESS clause for auxiliary objects is "not-accessible", except in the following circumstances:

  1. within a MIB module originally written to conform to the SNMPv1 framework, and later converted to conform to the SNMPv2 framework; or
  2. a conceptual row MUST contain at least one columnar object which is not an auxiliary object. If all of a conceptual row's columnar objects are also specified in its INDEX clause, then one of them MUST be accessible, i.e., have a MAX-ACCESS clause of "read-only". (Note that this situation does not arise for a conceptual row allowing create access, since such a row will have a status column which will not be an auxiliary object.)

Note that objects specified in a conceptual row's INDEX clause need not be columnar objects of that conceptual row. In this situation, the DESCRIPTION clause of the conceptual row MUST include a textual explanation of how the objects which are included in the INDEX clause but are not columnar objects of that conceptual row are used to uniquely identify instances of the conceptual row's columnar objects ๐Ÿงฉ

7.8. Mapping of the AUGMENTS clause โž•

The AUGMENTS clause, which MUST NOT be present unless the object corresponds to a conceptual row, is an alternative to the INDEX clause. Every object corresponding to a conceptual row has either an INDEX clause or an AUGMENTS clause ๐Ÿ’–

If an object corresponding to a conceptual row has an INDEX clause, that row is called a base conceptual row. If the object has an AUGMENTS clause instead, the row is said to be a conceptual row augmentation, and the AUGMENTS clause names the object corresponding to the base conceptual row that this augmentation extends. (Thus, a conceptual row augmentation cannot itself be augmented.) Instances of subordinate columnar objects of a conceptual row augmentation are identified according to the INDEX clause of the base conceptual row corresponding to the object named in the AUGMENTS clause. Also, instances of subordinate columnar objects of a conceptual row augmentation exist under the same semantics as instances of subordinate columnar objects of the base conceptual row being augmented. So note that creating a base conceptual row implies the corresponding creation of any conceptual row augmentations ๐ŸŒˆ

For example, a MIB designer might want to define additional columns in an "enterprise-specific" MIB that logically extend a conceptual row in a "standard" MIB. The "standard" MIB definition of the conceptual row would include the INDEX clause, and the "enterprise-specific" MIB would contain the definition of a conceptual row using the AUGMENTS clause. On the other hand, it would be incorrect to use the AUGMENTS clause for the relationship between RFC 1573's ifTable and the many media-specific MIBs that extend it for specific media (e.g., the dot3Table in RFC 1650), since not all interfaces are of the same media ๐Ÿ™…โ€โ™€๏ธ

Note that a base conceptual row MAY be augmented by multiple conceptual row augmentations.

7.8.1. Relation between INDEX and AUGMENTS clauses ๐Ÿง 

When defining instance identification information for a conceptual table:

  1. If there is a one-to-one correspondence between the conceptual rows of this table and an existing table, then the AUGMENTS clause SHOULD be used.
  2. Otherwise, if there is a sparse relationship between the conceptual rows of this table and an existing table, then an INDEX clause SHOULD be used that is identical to the one in the existing table. For example, the relationship between RFC 1573's ifTable and a media-specific MIB that extends the ifTable for a specific media (e.g., the dot3Table in RFC 1650) is a sparse relationship ๐ŸŒ™
  3. Otherwise, if no existing objects have the required syntax and semantics, then auxiliary objects SHOULD be defined within the conceptual row for the new table, and those objects SHOULD be used within the INDEX clause for the conceptual row ๐Ÿ› ๏ธ

7.9. Mapping of the DEFVAL clause ๐Ÿ“

The DEFVAL clause, which need not be present, defines an acceptable default value which MAY be used at the discretion of a SNMPv2 entity acting in an agent role when an object instance is created ๐Ÿช„

During conceptual row creation, if an instance of a columnar object is not present as one of the operands in the corresponding management protocol set operation, then the value of the DEFVAL clause, if present, indicates an acceptable default value that a SNMPv2 entity acting in an agent role might use ๐Ÿ’ซ

The value of the DEFVAL clause MUST, of course, correspond to the SYNTAX clause for the object. If the value is an OBJECT IDENTIFIER, then it MUST be expressed as a single ASN.1 identifier, and not as a collection of sub-identifiers ๐Ÿ“

Note that if an operand to the management protocol set operation is an instance of a read-only object, then the error `notWritable' [6] will be returned. As such, the DEFVAL clause can be used to provide an acceptable default value that a SNMPv2 entity acting in an agent role might use ๐Ÿ™

By way of example, consider the following possible DEFVAL clauses:

     ObjectSyntax       DEFVAL clause
     ----------------   ------------
     Integer32          DEFVAL { 1 }
                        -- same for Gauge32, TimeTicks, Unsigned32
     INTEGER            DEFVAL { valid } -- enumerated value
     OCTET STRING       DEFVAL { 'ffffffffffff'H }
     OBJECT IDENTIFIER  DEFVAL { sysDescr }
     BITS               DEFVAL { { primary, secondary } }
                        -- enumerated values that are set
     IpAddress          DEFVAL { 'c0210415'H } -- 192.33.4.21
Object types with SYNTAX of Counter32 and Counter64 may not have DEFVAL clauses, since they do not have defined initial values. However, it is RECOMMENDED that they be initialized to zero. โš ๏ธ

7.10. Mapping of the OBJECT-TYPE value ๐Ÿท๏ธ

The value of an invocation of the OBJECT-TYPE macro is the name of the object. That name is an OBJECT IDENTIFIER, an administratively assigned name ๐Ÿชช

When an OBJECT IDENTIFIER is assigned to an object:

  1. If the object corresponds to a conceptual table, then only a single assignment, the one for a conceptual row, is present immediately beneath that object. The administratively assigned name for the conceptual row object is derived by appending a sub-identifier of "1" to the administratively assigned name for the conceptual table ๐ŸŒท
  2. If the object corresponds to a conceptual row, then at least one assignment, one for each column in the conceptual row, is present beneath that object. The administratively assigned name for each column is derived by appending a unique, positive sub-identifier to the administratively assigned name for the conceptual row โœจ

Okay so, the last sub-identifier of any administratively assigned name for an object shall be positive, bestie ๐Ÿ’…. A zero-valued final sub-identifier is reserved for future use ๐Ÿ”’.

Also, even though conceptual tables and rows get administratively assigned names, the management protocol may not manipulate these conceptual objects in aggregate form ๐Ÿ™…โ€โ™€๏ธ

7.11. Usage Example ๐ŸŽ€

Let's look at how you'd define a conceptual table and all its subordinates. (This example uses the RowStatus textual convention defined in [3].) ๐Ÿ’–

evalSlot OBJECT-TYPE
    SYNTAX      INTEGER
    MAX-ACCESS  read-only
    STATUS      current
    DESCRIPTION
            "The index number of the first unassigned entry in the
            evaluation table.

            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."
    ::= { eval 1 }

evalTable OBJECT-TYPE
    SYNTAX      SEQUENCE OF EvalEntry
    MAX-ACCESS  not-accessible
    STATUS      current
    DESCRIPTION

            "The (conceptual) evaluation table."
    ::= { eval 2 }

evalEntry OBJECT-TYPE
    SYNTAX      EvalEntry
    MAX-ACCESS  not-accessible
    STATUS      current
    DESCRIPTION
            "An entry (conceptual row) in the evaluation table."
    INDEX   { evalIndex }
    ::= { evalTable 1 }

EvalEntry ::=
    SEQUENCE {
        evalIndex       Integer32,
        evalString      DisplayString,
        evalValue       Integer32,
        evalStatus      RowStatus
    }

evalIndex OBJECT-TYPE
    SYNTAX      Integer32
    MAX-ACCESS  not-accessible
    STATUS      current
    DESCRIPTION
            "The auxiliary variable used for identifying instances of
            the columnar objects in the evaluation table."
        ::= { evalEntry 1 }

evalString OBJECT-TYPE
    SYNTAX      DisplayString
    MAX-ACCESS  read-create
    STATUS      current
    DESCRIPTION
            "The string to evaluate."
        ::= { evalEntry 2 }

evalValue OBJECT-TYPE
    SYNTAX      Integer32
    MAX-ACCESS  read-only
    STATUS      current
    DESCRIPTION
            "The value when evalString was last executed."
    DEFVAL  { 0 }
        ::= { evalEntry 3 }

evalStatus OBJECT-TYPE
    SYNTAX      RowStatus
    MAX-ACCESS  read-create
    STATUS      current
    DESCRIPTION
            "The status column used for creating, modifying, and
            deleting instances of the columnar objects in the evaluation
            table."
    DEFVAL  { active }
        ::= { evalEntry 4 }

8. Mapping of the NOTIFICATION-TYPE macro ๐Ÿ””

The NOTIFICATION-TYPE macro defines the information inside an unsolicited transmission of management information, meaning either a SNMPv2-Trap-PDU or an InformRequest-PDU. Heads up: expanding the NOTIFICATION-TYPE macro is something that conceptually happens during implementation, not at run-time โœจ

8.1. Mapping of the OBJECTS clause ๐Ÿ“‹

The OBJECTS clause need not be present. When it is, it defines the ordered sequence of MIB object types contained within every instance of the notification. An object type listed here may not have a MAX-ACCESS clause of "not-accessible". ๐Ÿ™ˆ

8.2. Mapping of the STATUS clause ๐Ÿšฆ

The STATUS clause must be present, and it shows whether the definition is current or historic.

The values "current" and "obsolete" are self-explanatory ๐Ÿ’โ€โ™€๏ธ The "deprecated" value means the definition is obsolete, but an implementor may still want to support the notification to keep things interoperable with older implementations ๐Ÿซถ

8.3. Mapping of the DESCRIPTION clause ๐Ÿ“

The DESCRIPTION clause must be present. It holds a textual definition of the notification with all the semantic details needed for implementation, and it should carry any info that would otherwise go in ASN.1 commentary annotations attached to the notification. Especially, the DESCRIPTION clause should document which instances of the objects named in the OBJECTS clause should be contained within notifications of this type. ๐Ÿง 

8.4. Mapping of the REFERENCE clause ๐Ÿ”—

The REFERENCE clause need not be present. It holds a textual cross-reference to a notification defined in some other information module. This comes in handy when de-osifying a MIB module that some other organization produced ๐ŸŒˆ

8.5. Mapping of the NOTIFICATION-TYPE value ๐Ÿท๏ธ

The value of a NOTIFICATION-TYPE invocation is the name of the notification. That name is an OBJECT IDENTIFIER, an administratively assigned name. To stay compatible with the procedures proxy agents use (see Section 3.1.2 of [7]), the next to last sub-identifier in the name of any newly-defined notification must have the value zero. ๐Ÿค“

Sections 4.2.6 and 4.2.7 of [6] explain how the NOTIFICATION-TYPE macro is used to generate a SNMPv2-Trap-PDU or an InformRequest-PDU, respectively. โœจ

8.6. Usage Example ๐ŸŽ€

Let's see how a linkUp trap might be described:

linkUp NOTIFICATION-TYPE
    OBJECTS { ifIndex }
    STATUS  current
    DESCRIPTION
            "A linkUp trap signifies that the SNMPv2 entity, acting in
            an agent role, recognizes that one of the communication
            links represented in its configuration has come up."
    ::= { snmpTraps 4 }

According to this invocation, the trap authoritatively identified as { snmpTraps 4 } is used to report a link coming up. That's giving link is up, we're so back ๐Ÿš€

9. Refined Syntax ๐Ÿ’…

Some macros have clauses that let you refine syntax. Specifically, that's the SYNTAX clause of the OBJECT-TYPE macro, and the SYNTAX/WRITE-SYNTAX clauses of the MODULE-COMPLIANCE and AGENT-CAPABILITIES macros [2]. Not every refinement is okay though ๐Ÿ˜ญ In particular, the object's primitive or application type must not be changed.

Further, the following restrictions apply:

                        Restrictions to Refinement on
object syntax         range   enumeration     size    repertoire
-----------------     -----   -----------     ----    ----------
          INTEGER      (1)        (2)           -         -
        Integer32      (1)         -            -         -
       Unsigned32      (1)         -            -         -
     OCTET STRING       -          -           (3)       (4)
OBJECT IDENTIFIER       -          -            -         -
             BITS       -         (2)           -         -
        IpAddress       -          -            -         -
        Counter32       -          -            -         -
        Counter64       -          -            -         -
          Gauge32      (1)         -            -         -
        TimeTicks       -          -            -         -

where:

  1. The range of permitted values may be refined by raising the lower-bounds, by reducing the upper-bounds, and/or by reducing the alternative value/range choices.
  2. The enumeration of named-values may be refined by removing one or more named-values. (Heads up: for BITS, a refinement may cause the enumerations to no longer be contiguous ๐Ÿ™ƒ)
  3. The size in characters of the value may be refined by raising the lower-bounds, by reducing the upper-bounds, and/or by reducing the alternative size choices; or,
  4. The repertoire of characters in the value may be reduced by further sub-typing.

Otherwise no refinements are possible. More details on sub-typing are in Appendix C. ๐Ÿฆ‹

10. Extending an Information Module ๐ŸŒธ

As experience builds up with a published information module, it may be desirable to revise that module. ๐Ÿงš

To begin, the invocation of the MODULE-IDENTITY macro should be updated to include info about the revision. Usually that means updating the LAST-UPDATED clause and adding a pair of REVISION and DESCRIPTION clauses. However, other existing clauses in the invocation may be updated too.

Note that the module's label (e.g., "FIZBIN-MIB" from the example in Section 5.8) does not change when the information module is revised. Iconic stability ๐Ÿ‘‘

10.1. Object Assignments ๐Ÿท๏ธ

If any non-editorial change is made to any clause of an object assignment, then the OBJECT IDENTIFIER value tied to that object assignment must also change, along with its associated descriptor. ๐Ÿ˜ค

10.2. Object Definitions ๐Ÿงฉ

An object definition may be revised in any of the following ways:

  1. A SYNTAX clause containing an enumerated INTEGER may have new enumerations added or existing labels changed.
  2. A STATUS clause value of "current" may be revised as "deprecated" or "obsolete". Similarly, a STATUS clause value of "deprecated" may be revised as "obsolete".
  3. A DEFVAL clause may be added or updated.
  4. A REFERENCE clause may be added or updated.
  5. A UNITS clause may be added.
  6. A conceptual row may be augmented by adding new columnar objects at the end of the row.
  7. Entirely new objects may be defined, named with previously unassigned OBJECT IDENTIFIER values.

Otherwise, if the semantics of any previously defined object change (meaning a non-editorial change is made to any clause other than those specifically allowed above), then the OBJECT IDENTIFIER value associated with that object must also change. ๐Ÿšจ

Note that changing the descriptor tied to an existing object counts as a semantic change, since these strings may be used in an IMPORTS statement. ๐Ÿ’€

Finally, if an object has its STATUS clause value changed, then its DESCRIPTION clause should be updated to match. โœจ

10.3. Notification Definitions ๐Ÿ””

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

  1. A REFERENCE clause may be added or updated.

Otherwise, if the semantics of any previously defined notification change (meaning a non-editorial change is made to any clause other than those specifically allowed above), then the OBJECT IDENTIFIER value associated with that notification must also change. ๐Ÿซ 

Note that changing the descriptor tied to an existing notification counts as a semantic change, since these strings may be used in an IMPORTS statement. ๐Ÿ™Œ

Finally, if an object has its STATUS clause value changed, then its DESCRIPTION clause should be updated to match. ๐ŸŒˆ

11. Appendix A: de-OSIfying a MIB module โœจ

okay so this appendix is basically the recipe for taking MIBs that other orgs (like the IEEE) already wrote and making them work with the Internet-standard network management framework ๐Ÿง there's been a lot of this lately, and the steps are super straightforward, just kinda tedious ๐Ÿ˜ฉ it helps a lot if you've already written MIB modules for this framework before, bestie ๐Ÿซถ

step one is building a skeletal MIB module, same as the one back in Section 5.8 ๐Ÿ’… step two is sorting the objects into groups. optional objects are not permitted, so any optional object has to go into an additional group, and if you implement that group, every object in it must be implemented too ๐Ÿ™ˆ for your first pass, the wisest move is to just ignore the optional objects in the original MIB. experience shows it's better to define a core MIB module first with only the essential objects, and then add other stuff later if experience says you need it ๐ŸŒธ

11.1. Managed Object Mapping ๐ŸŽ€

next, for each managed object class, figure out whether multiple instances of that class can exist. if they can't, then for each of its attributes, use the OBJECT-TYPE macro to make an equivalent definition.

if multiple instances can exist, then define a conceptual table with conceptual rows, and each row gets a columnar object for each of the managed object class's attributes ๐Ÿฆ‹ and if the class sits inside the containment tree of another managed object class, you usually need an object assigned for each of the "distinguished attributes" of the containing class. if those don't already exist in the MIB module, you can add them as extra columnar objects in the conceptual row for the contained class โœจ

when you're defining a conceptual row, think about how network management operations are going to act on its columnar objects ๐Ÿ‘€ the big thing is avoiding more columnar objects in one row than can fit in a single PDU. as a rule of thumb, a conceptual row should have no more than about 20 objects. the same idea goes for the "20 object guideline": group columnar objects into tables based on how network management operations are expected to hit them. so the contents of each row should match typical access patterns, like organizing by function (one row for statistics, another for parameters) or by usage (commonly-needed objects versus rarely-needed ones) ๐Ÿ’œ

but also, don't make conceptual rows where the number of columnar objects used as indexes outnumbers the ones holding actual information ๐Ÿ™…โ€โ™€๏ธ and don't split a managed object class's attributes across a bunch of conceptual tables just to get the same flexibility and complexity you'd see in MIBs with a myriad of optionals. that's a no, periodt ๐Ÿ’€

11.1.1. Mapping to the SYNTAX clause ๐Ÿ“

when you're mapping to the SYNTAX clause of the OBJECT-TYPE macro:

(1) an object with BOOLEAN syntax becomes a TruthValue [3].

(2) an object with INTEGER syntax becomes an Integer32.

(3) an object with ENUMERATED syntax becomes an INTEGER with enumerations, taking any of the given values that can be represented with an Integer32.

(4) an object with BIT STRING syntax that has enumerations becomes a BITS construct.

(5) an object with BIT STRING syntax but no enumerations becomes an OCTET STRING.

(6) an object with a character string syntax becomes either an OCTET STRING or a DisplayString [3], depending on the repertoire of the character string.

(7) a non-tabular object with a complex syntax, like REAL or EXTERNAL, must be decomposed, usually into an OCTET STRING (if that makes sense). as a rule, any object with a complicated syntax should be avoided ๐Ÿ˜ญ

(8) tabular objects must be decomposed into rows of columnar objects ๐Ÿงš

11.1.2. Mapping to the UNITS clause ๐Ÿ“

if the description of this managed object defines a unit-basis, then mapping to this clause is straightforward โœจ

11.1.3. Mapping to the MAX-ACCESS clause ๐Ÿ”‘

this is straightforward ๐Ÿ’…

11.1.4. Mapping to the STATUS clause ๐ŸŒˆ

this is straightforward ๐Ÿ’–

11.1.5. Mapping to the DESCRIPTION clause ๐Ÿ“

this is straightforward: just copy the text, but make sure any embedded double quotation marks get sanitized (so swap them for single-quotes or remove them) ๐Ÿซถ

11.1.6. Mapping to the REFERENCE clause ๐Ÿ”–

this is straightforward too: include a textual reference to the object being mapped, the document that defines the object, and maybe a page number in that document ๐Ÿ“–

11.1.7. Mapping to the INDEX clause ๐Ÿ—‚๏ธ

if it's necessary, decide how instance-identifiers for columnar objects are going to be formed, and define this clause to match ๐Ÿงฉ

11.1.8. Mapping to the DEFVAL clause ๐ŸŽฏ

decide whether a meaningful default value can be assigned to the object you're mapping. if it can, define the DEFVAL clause accordingly ๐Ÿ’œ

11.2. Action Mapping โšก

actions get modeled as read-write objects, where writing a particular value causes a state change. (usually, as part of that state change, some action happens too ๐Ÿ”ฅ)

11.2.1. Mapping to the SYNTAX clause ๐Ÿญ

usually you use the Integer32 syntax, with a distinguished value for each action the object gives access to. there's usually also one other distinguished value, which is the one returned when the object is read ๐ŸŒธ

11.2.2. Mapping to the MAX-ACCESS clause ๐Ÿ”

always use read-write or read-create ๐ŸŽ€

11.2.3. Mapping to the STATUS clause ๐ŸŒท

this is straightforward โœจ

11.2.4. Mapping to the DESCRIPTION clause ๐Ÿ“

this is straightforward: copy the text, and sanitize any embedded double quotation marks (replace them with single-quotes or remove them) ๐Ÿ’…

11.2.5. Mapping to the REFERENCE clause ๐Ÿ”–

this is straightforward: include a textual reference to the action being mapped, the document that defines the action, and maybe a page number ๐Ÿ“š

11.3. Event Mapping ๐Ÿ””

events get modeled as SNMPv2 notifications using the NOTIFICATION-TYPE macro. but remember, SNMPv2 leans heavily on trap-directed polling ๐Ÿฆ‹ so few notifications, and usually none, need to be defined for any MIB module ๐ŸŒ™

11.3.1. Mapping to the STATUS clause ๐ŸŒผ

this is straightforward โœจ

11.3.2. Mapping to the DESCRIPTION clause ๐Ÿ“

this is straightforward: copy the text and sanitize any embedded double quotation marks (replace them with single-quotes or remove them) ๐Ÿซถ

11.3.3. Mapping to the REFERENCE clause ๐Ÿ”–

this is straightforward: include a textual reference to the notification being mapped, the document that defines the notification, and maybe a page number ๐Ÿ’–


12. Appendix B: UTC Time Format ๐Ÿ•ฐ๏ธ

several clauses in this document use the UTC Time format, which looks like this:

YYMMDDHHMMZ

where: YY - last two digits of year
       MM - month (01 through 12)
       DD - day of month (01 through 31)
       HH - hours (00 through 23)
       MM - minutes (00 through 59)
        Z - the character "Z" denotes Greenwich Mean Time (GMT).

for example, "9502192015Z" represents 8:15pm GMT on 19 February 1995 ๐ŸŒ™โœจ


13. Appendix C: Detailed Sub-typing Rules ๐Ÿง

13.1. Syntax Rules ๐Ÿ“

here are the syntax rules for sub-typing. this syntax is based on ASN.1, but it has some extensions beyond what ASN.1 allows, and a bunch of ASN.1 constructs aren't allowed by this syntax at all ๐Ÿค“

<integerSubType>
    ::= <empty>
      | "(" <range> ["|" <range>]... ")"

<octetStringSubType>
    ::= <empty>
      | "(" "SIZE" "(" <range> ["|" <range>]... ")" ")"

<range>
    ::= <value>
      | <value> ".." <value>

<value>
    ::= "-" <number>
      | <number>
      | <hexString>
      | <binString>

where:
    <empty>     is the empty string
    <number>    is a non-negative integer
    <hexString> is a hexadecimal string (i.e. 'xxxx'H)
    <binString> is a binary string (i.e. 'xxxx'B)
    <range> is further restricted as follows:
        - any <value> used in a SIZE clause must be non-negative.
        - when a pair of values is specified, the first value
          must be less than the second value.
        - when multiple ranges are specified, the ranges may
          not overlap but may touch. For example, (1..4 | 4..9)
          is invalid, and (1..4 | 5..9) is valid.
        - the ranges must be a subset of the maximum range of the
          base type.

13.2. Examples ๐ŸŽ€

here are some examples of legal sub-typing ๐Ÿ’…

Integer32 (-20..100)
Integer32 (0..100 | 300..500)
Integer32 (300..500 | 0..100)
Integer32 (0 | 2 | 4 | 6 | 8 | 10)
OCTET STRING (SIZE(0..100))
OCTET STRING (SIZE(0..100 | 300..500))
OCTET STRING (SIZE(0 | 2 | 4 | 6 | 8 | 10))

and here are some examples of illegal sub-typing, which is a big no ๐Ÿ™…โ€โ™€๏ธ

Integer32 (150..100)         -- first greater than second
Integer32 (0..100 | 50..500) -- ranges overlap
Integer32 (0 | 2 | 0 )       -- value duplicated
Integer32 (MIN..-1 | 1..MAX) -- MIN and MAX not allowed
Integer32 ((SIZE (0..34))    -- must not use SIZE
OCTET STRING (0..100)        -- must use SIZE
OCTET STRING (SIZE(-10..100)) -- negative SIZE

13.3. Rules for Textual Conventions ๐Ÿฆ‹

sub-typing of Textual Conventions (see [3]) is allowed, but it must be valid. specifically, each range you specify for the textual convention must be a subset of a range specified for the base type. for example:

Tc1 ::= INTEGER (1..10 | 11..20)
Tc2 ::= Tc1 (2..10 | 12..15)       -- is valid
Tc3 ::= Tc1 (4..8)                 -- is valid
Tc4 ::= Tc1 (8..12)                -- is invalid

14. Security Considerations ๐Ÿšจ

security issues are not discussed in this memo. no cap, this is a big deal and the whole document is deliberately silent on it, so don't assume anything is covered here ๐Ÿ˜ณ

15. Editor's Address ๐Ÿ’Œ

Keith McCloghrie
Cisco Systems, Inc.
170 West Tasman Drive
San Jose, CA  95134-1706
US

Phone: +1 408 526 5260
EMail: kzm@cisco.com

16. Acknowledgements ๐ŸŽ€

okay bestie, this part is all about the people who made this RFC happen ๐Ÿซถ โœจ four major contributors did the heavy lifting, and they're listed right here ๐Ÿ’…

Jeffrey D. Case (SNMP Research, case@snmp.com) ๐ŸŒธ Keith McCloghrie (Cisco Systems, kzm@cisco.com) ๐ŸŒธ Marshall T. Rose (Dover Beach Consulting, mrose@dbc.mtview.ca.us) ๐ŸŒธ Steven Waldbusser (International Network Services, stevew@uni.ins.com) ๐ŸŒธ

ngl the list keeps going because the whole SNMPv2 Working Group got thanked too ๐Ÿ’– there's a special shoutout for a bunch of people who contributed a lot, so let's give them their flowers ๐ŸŒท

Alexander I. Alten (Novell) ๐Ÿฆ‹ Dave Arneson (Cabletron) ๐Ÿฆ‹ Uri Blumenthal (IBM) ๐Ÿฆ‹ Doug Book (Chipcom) ๐Ÿฆ‹ Kim Curran (Bell-Northern Research) ๐Ÿฆ‹ Jim Galvin (Trusted Information Systems) ๐Ÿฆ‹ Maria Greene (Ascom Timeplex) ๐Ÿฆ‹ Iain Hanson (Digital) ๐Ÿฆ‹ Dave Harrington (Cabletron) ๐Ÿฆ‹ Nguyen Hien (IBM) ๐Ÿฆ‹ Jeff Johnson (Cisco Systems) ๐Ÿฆ‹ Michael Kornegay (Object Quest) ๐Ÿฆ‹ Deirdre Kostick (AT&T Bell Labs) ๐Ÿฆ‹ David Levi (SNMP Research) ๐Ÿฆ‹ Daniel Mahoney (Cabletron) ๐Ÿฆ‹ Bob Natale (ACE*COMM) ๐Ÿฆ‹ Brian O'Keefe (Hewlett Packard) ๐Ÿฆ‹ Andrew Pearson (SNMP Research) ๐Ÿฆ‹ Dave Perkins (Peer Networks) ๐Ÿฆ‹ Randy Presuhn (Peer Networks) ๐Ÿฆ‹ Aleksey Romanov (Quality Quorum) ๐Ÿฆ‹ Shawn Routhier (Epilogue) ๐Ÿฆ‹ Jon Saperia (BGS Systems) ๐Ÿฆ‹ Bob Stewart (Cisco Systems, bstewart@cisco.com), chair ๐Ÿ‘‘ Kaj Tesink (Bellcore) ๐Ÿฆ‹ Glenn Waters (Bell-Northern Research) ๐Ÿฆ‹ Bert Wijnen (IBM) ๐Ÿฆ‹


17. References ๐Ÿ“š

okay so the references are the other specs this one leans on, and you need them to make sense of everything ๐Ÿงš each one is listed with all its details ๐Ÿ’…

[1] Information processing systems - Open Systems Interconnection - Specification of Abstract Syntax Notation One (ASN.1), International Organization for Standardization. International Standard 8824, (December, 1987).

[2] SNMPv2 Working Group, Case, J., McCloghrie, K., Rose, M., and S. Waldbusser, "Conformance Statements for Version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1904, January 1996.

[3] SNMPv2 Working Group, Case, J., McCloghrie, K., Rose, M., and S. Waldbusser, "Textual Conventions for Version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1903, January 1996.

[4] Information processing systems - Open Systems Interconnection - Specification of Basic Encoding Rules for Abstract Syntax Notation One (ASN.1), International Organization for Standardization. International Standard 8825, (December, 1987).

[5] SNMPv2 Working Group, Case, J., McCloghrie, K., Rose, M., and S. Waldbusser, "Management Information Base for Version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1907, January 1996.

[6] SNMPv2 Working Group, Case, J., McCloghrie, K., Rose, M., and S. Waldbusser, "Protocol Operations for Version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1905, January 1996.

[7] SNMPv2 Working Group, Case, J., McCloghrie, K., Rose, M., and S. Waldbusser, "Coexistence between Version 1 and Version 2 of the Internet-standard Network Management Framework", RFC 1908, January 1996.

๐Ÿ“ฆ where this page comes from