RFC 1442

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

๐Ÿ“… published April 1993, from ietf

Okay bestie, let's get into RFC 1442! ๐ŸŽ€โœจ It's titled Structure of Management Information for version 2 of the Simple Network Management Protocol (SNMPv2), and it's the RFC that defines the SMI (the Structure of Management Information) for SNMPv2. ๐Ÿ’–

The authors are J. Case from SNMP Research, Inc., K. McCloghrie from Hughes LAN Systems, M. Rose from Dover Beach Consulting, Inc., and S. Waldbusser from Carnegie Mellon University. ๐Ÿซถ It's from the Network Working Group, the RFC number is 1442, and it's dated April 1993. ๐ŸŒธ

It's an IAB standards track protocol for the Internet community. โœจ The title block doesn't list any RFCs that it obsoletes or updates. ๐Ÿ™ˆ


Status of This Memo ๐Ÿ“œ

So the status part says this is an IAB standards track protocol for the Internet community, and it asks for discussion and suggestions for improvements. ๐Ÿ’… If you want the current standardization state and status of this protocol, go check the current edition of the "IAB Official Protocol Standards." ๐Ÿ‘‘ And distribution of this memo is unlimited, so share it with everyone! ๐Ÿฆ‹


Table of Contents

          1 Introduction ..........................................    2
          1.1 A Note on Terminology ...............................    3
          2 Definitions ...........................................    4
          3.1 The MODULE-IDENTITY macro ...........................    5
          3.2 Object Names and Syntaxes ...........................    7
          3.3 The OBJECT-TYPE macro ...............................   10
          3.5 The NOTIFICATION-TYPE macro .........................   12
          3 Information Modules ...................................   13
          3.1 Macro Invocation ....................................   13
          3.1.1 Textual Clauses ...................................   14
          3.2 IMPORTing Symbols ...................................   14
          4 Naming Hierarchy ......................................   16
          5 Mapping of the MODULE-IDENTITY macro ..................   17
          5.1 Mapping of the LAST-UPDATED clause ..................   17
          5.2 Mapping of the ORGANIZATION clause ..................   17
          5.3 Mapping of the CONTACT-INFO clause ..................   17
          5.4 Mapping of the DESCRIPTION clause ...................   17
          5.5 Mapping of the REVISION clause ......................   17
          5.6 Mapping of the DESCRIPTION clause ...................   18
          5.7 Mapping of the MODULE-IDENTITY value ................   18
          5.8 Usage Example .......................................   19
          6 Mapping of the OBJECT-IDENTITY macro ..................   20
          6.1 Mapping of the STATUS clause ........................   20
          6.2 Mapping of the DESCRIPTION clause ...................   20
          6.3 Mapping of the REFERENCE clause .....................   20
          6.4 Mapping of the OBJECT-IDENTITY value ................   20
          6.5 Usage Example .......................................   21
          7 Mapping of the OBJECT-TYPE macro ......................   22
          7.1 Mapping of the SYNTAX clause ........................   22
          7.1.1 Integer32 and INTEGER .............................   22
          7.1.2 OCTET STRING ......................................   23
          7.1.3 OBJECT IDENTIFIER .................................   23
          7.1.4 BIT STRING ........................................   23
          7.1.5 IpAddress .........................................   23
          7.1.6 Counter32 .........................................   24
          7.1.7 Gauge32 ...........................................   24
          7.1.8 TimeTicks .........................................   24
          7.1.9 Opaque ............................................   25
          7.1.10 NsapAddress ......................................   25
          7.1.11 Counter64 ........................................   26
          7.1.12 UInteger32 .......................................   26
          7.2 Mapping of the UNITS clause .........................   26
          7.3 Mapping of the MAX-ACCESS clause ....................   27
          7.4 Mapping of the STATUS clause ........................   27
          7.5 Mapping of the DESCRIPTION clause ...................   27
          7.6 Mapping of the REFERENCE clause .....................   28
          7.7 Mapping of the INDEX clause .........................   28
          7.7.1 Creation and Deletion of Conceptual Rows ..........   30
          7.8 Mapping of the AUGMENTS clause ......................   31
          7.8.1 Relation between INDEX and AUGMENTS clauses .......   31
          7.9 Mapping of the DEFVAL clause ........................   32
          7.10 Mapping of the OBJECT-TYPE value ...................   33
          7.11 Usage Example ......................................   35
          8 Mapping of the NOTIFICATION-TYPE macro ................   37
          8.1 Mapping of the OBJECTS clause .......................   37
          8.2 Mapping of the STATUS clause ........................   37
          8.3 Mapping of the DESCRIPTION clause ...................   37
          8.4 Mapping of the REFERENCE clause .....................   37
          8.5 Mapping of the NOTIFICATION-TYPE value ..............   38
          8.6 Usage Example .......................................   39
          9 Refined Syntax ........................................   40
          10 Extending an Information Module ......................   41
          10.1 Object Assignments .................................   41
          10.2 Object Definitions .................................   41
          10.3 Notification Definitions ...........................   42
          11 Appendix: de-OSIfying a MIB module ...................   43
          11.1 Managed Object Mapping .............................   43
          11.1.1 Mapping to the SYNTAX clause .....................   44
          11.1.2 Mapping to the UNITS clause ......................   45
          11.1.3 Mapping to the MAX-ACCESS clause .................   45
          11.1.4 Mapping to the STATUS clause .....................   45
          11.1.5 Mapping to the DESCRIPTION clause ................   45
          11.1.6 Mapping to the REFERENCE clause ..................   45
          11.1.7 Mapping to the INDEX clause ......................   45
          11.1.8 Mapping to the DEFVAL clause .....................   45
          11.2 Action Mapping .....................................   46
          11.2.1 Mapping to the SYNTAX clause .....................   46
          11.2.2 Mapping to the MAX-ACCESS clause .................   46
          11.2.3 Mapping to the STATUS clause .....................   46
          11.2.4 Mapping to the DESCRIPTION clause ................   46
          11.2.5 Mapping to the REFERENCE clause ..................   46
          11.3 Event Mapping ......................................   46
          11.3.1 Mapping to the STATUS clause .....................   47
          11.3.2 Mapping to the DESCRIPTION clause ................   47
          11.3.3 Mapping to the REFERENCE clause ..................   47
          12 Acknowledgements .....................................   48
          13 References ...........................................   52
          14 Security Considerations ..............................   54
          15 Authors' Addresses ...................................   54

1. Introduction โœจ

Okay so, a network management system has a few main pieces. ๐Ÿงš You've got several (potentially many) nodes, and each one has a processing entity called an agent that can get to the management instrumentation. ๐Ÿ’œ Then you need at least one management station, plus a management protocol that moves management information between the agents and the stations. ๐ŸŒˆ All of this runs under an administrative framework that defines both authentication and authorization policies. ๐Ÿ”ฅ

Management stations run management applications that monitor and control network elements. ๐Ÿ’… Network elements are things like hosts, routers, terminal servers, and so on, and you monitor and control them by getting access to their management information. ๐Ÿ“

The management information is seen as a collection of managed objects, living in a virtual information store called the Management Information Base (MIB). ๐Ÿฆ‹ Related objects get grouped together into MIB modules, and those modules are written using a subset of OSI's Abstract Syntax Notation One (ASN.1) [1]. ๐ŸŒธ This document, the Structure of Management Information (SMI), is what defines that subset. ๐ŸŽ€

The SMI is split into three parts: module definitions, object definitions, and trap definitions. ๐Ÿ˜ญ

  • (1) Module definitions describe information modules. An ASN.1 macro called MODULE-IDENTITY concisely conveys the semantics of an information module. ๐Ÿ’–
  • (2) Object definitions describe managed objects. An ASN.1 macro called OBJECT-TYPE concisely conveys the syntax and semantics of a managed object. โœจ
  • (3) Notification definitions describe unsolicited transmissions of management information. An ASN.1 macro called NOTIFICATION-TYPE concisely conveys the syntax and semantics of a notification. ๐Ÿ”ฅ

1.1. A Note on Terminology ๐Ÿ’ฌ

Just for clarity, the original Internet-standard Network Management Framework, the one described in RFCs 1155, 1157, and 1212, is called the SNMP version 1 framework (SNMPv1). ๐Ÿ™ˆ The current framework is called the SNMP version 2 framework (SNMPv2). ๐Ÿ‘‘


2. Definitions ๐ŸŽ€

Here's the start of the actual SMI definitions. ๐Ÿงš Keep an eye out for the path to the root, the module identities, and the MODULE-IDENTITY macro, which is the first big chunk. ๐Ÿ’œ

SNMPv2-SMI DEFINITIONS ::= BEGIN


          -- the path to the root

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

          directory      OBJECT IDENTIFIER ::= { internet 1 }

          mgmt           OBJECT IDENTIFIER ::= { internet 2 }

          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"
                          | "obsolete"

              ReferPart ::=
                          "REFERENCE" Text
                        | empty

              Text ::= """" string """"
          END
          -- names of objects

          ObjectName ::=
              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
                      INTEGER (-2147483648..2147483647),

                  string-value
                      OCTET STRING,

                  objectID-value
                      OBJECT IDENTIFIER,

                  -- only the enumerated form is allowed
                  bit-value
                      BIT STRING
              }

          -- 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,

                  gauge-value
                      Gauge32,

                  timeticks-value
                      TimeTicks,

                  arbitrary-value
                      Opaque,

                  nsapAddress-value
                      NsapAddress,

                  big-counter-value
                      Counter64,

                  unsigned-integer-value
                      UInteger32
              }

          -- 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)

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

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

          -- for OSI NSAP addresses
          -- (this is a tagged type for historical reasons)
          NsapAddress ::=
              [APPLICATION 5]
                  IMPLICIT OCTET STRING (SIZE (1 | 4..21))

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

          -- an unsigned 32-bit quantity
          UInteger32 ::=
              [APPLICATION 7]
                  IMPLICIT INTEGER (0..4294967295)

          -- definition for objects

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

              VALUE NOTATION ::=
                            value(VALUE ObjectName)

              UnitsPart ::=
                            "UNITS" Text
                          | empty

              Access ::=
                            "not-accessible"
                          | "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 OBJECT IDENTIFIER)

              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


          END

3. Information Modules โœจ

An "information module" is an ASN.1 module defining information relating to network management. ๐Ÿง 

The SMI describes how to use a subset of ASN.1 to define an information module. Further, additional restrictions are placed on "standard" information modules. It is strongly recommended that "enterprise-specific" information modules also adhere to these restrictions. ๐Ÿ’…

Typically, there are three kinds of information modules: ๐ŸŽ€

  1. MIB modules, which contain definitions of inter-related managed objects, 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].

This classification scheme does not imply a rigid taxonomy. For example, a "standard" information module might include definitions of managed objects and a compliance statement. Similarly, an "enterprise-specific" information module might include definitions of managed objects and a capability statement. Of course, a "standard" information module may not contain capability statements. ๐Ÿฆ‹

All information modules start with exactly one invocation of the MODULE-IDENTITY macro, which provides contact and revision history. This invocation must appear immediately after any IMPORTs or EXPORTs statements. ๐Ÿ‘‘

3.1. Macro Invocation ๐ŸŒธ

Within an information module, each macro invocation appears as:

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

where <descriptor> corresponds to an ASN.1 identifier, <macro> names the macro being invoked, and <clauses> and <value> depend on the definition of the macro.

An ASN.1 identifier consists of one or more letters, digits, or hyphens. The initial character must be a lower-case letter, and the final character may not be a hyphen. Further, a hyphen may not be immediatedly followed by another hyphen. ๐Ÿ“

For all descriptors appearing in an information module, the descriptor shall be unique and mnemonic, and shall not exceed 64 characters in length. This promotes a common language for humans to use when discussing the information module and also facilitates simple table mappings for user-interfaces. โœจ

The set of descriptors defined in all "standard" information modules shall be unique. Further, within any information module, the hyphen is not allowed as a character in any descriptor. ๐Ÿ™ˆ

Finally, by convention, if the descriptor refers to an object with a SYNTAX clause value of either Counter32 or Counter64, then the descriptor used for the object should denote plurality. ๐Ÿงš

3.1.1. Textual Clauses ๐Ÿ’œ

Some clauses in a macro invocation may take a textual value (e.g., the DESCRIPTION clause). Note that, in order to conform to the ASN.1 syntax, the entire value of these clauses must be enclosed in double quotation marks, and therefore cannot itself contain double quotation marks, although the value may be multi-line. ๐Ÿ˜ญ

3.2. IMPORTing Symbols ๐ŸŒˆ

To reference an external object, the IMPORTS statement must be used to identify both the descriptor and the module defining the descriptor. ๐Ÿซถ

Note that when symbols from "enterprise-specific" information modules are referenced (e.g., a descriptor), there is the possibility of collision. As such, if different objects with the same descriptor are IMPORTed, then this ambiguity is resolved by prefixing the descriptor with the name of the information module and a dot ("."), i.e.,

     "module.descriptor"

(All descriptors must be unique within any information module.) ๐Ÿ”ฅ

Of course, this notation can be used even when there is no collision when IMPORTing symbols. ๐Ÿ’–

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

4. Naming Hierarchy โœจ

okay bestie, let's talk about where everything lives in the tree ๐ŸŒณ The root of the subtree that IANA (the Internet Assigned Numbers Authority) runs for the Internet is:

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

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

1.3.6.1.

A few branches under it 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 }

However, the SMI does not prohibit the definition of objects in other portions of the object tree. So it's not like it bans you from putting things elsewhere ๐Ÿ™ƒ

The mgmt(2) subtree is used to identify "standard" objects. Standard = main character energy ๐Ÿ‘‘

The experimental(3) subtree is used to identify objects being designed by working groups of the IETF. Now here's the tea ๐Ÿต If an information module produced by a working group becomes a "standard" information module, then at the very beginning of its entry onto the Internet standards track, the objects are moved under the mgmt(2) subtree. So it's like graduating from experimental to the mgmt glow-up ๐ŸŽ“โœจ

The private(4) subtree is used to identify objects defined unilaterally. The enterprises(1) subtree beneath private is used, among other things, to permit providers of networking subsystems to register models of their products. Providers get their own little corner to show off their products ๐Ÿงš

5. Mapping of the MODULE-IDENTITY macro

okay so the MODULE-IDENTITY macro is basically the contact card 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 is something which conceptually happens during implementation and not during run-time. Think of it as happening at build time, not while the thing is running ๐Ÿซถ

5.1. Mapping of the LAST-UPDATED clause

The LAST-UPDATED clause, which must be present, contains the date and time that this information module was last edited. Receipts, bestie ๐Ÿ“…

5.2. Mapping of the ORGANIZATION clause

The ORGANIZATION clause, which must be present, contains a textual description of the organization under whose auspices this information module was developed. Who's the squad behind it? This clause tells you ๐Ÿ’œ

5.3. Mapping of the CONTACT-INFO clause

The CONTACT-INFO clause, which must be present, contains the name, postal address, telephone number, and electronic mail address of the person to whom technical queries concerning this information module should be sent. So this is where you slide into the DMs of the right person ๐Ÿ“ฌ

5.4. Mapping of the DESCRIPTION clause

The DESCRIPTION clause, which must be present, contains a high-level textual description of the contents of this information module. Short and sweet summary, no cap โœจ

5.5. Mapping of the REVISION clause

The REVISION clause, which need not be present, is repeatedly used to describe the revisions made to this information module, in reverse chronological order. Each instance of this clause contains the date and time of the revision. So newest drama first, always ๐Ÿ”ฅ

5.6. Mapping of the DESCRIPTION clause

The DESCRIPTION clause, which must be present for each REVISION clause, contains a high-level textual description of the revision identified in that REVISION clause. So every revision gets its own little recap ๐Ÿ“

5.7. Mapping of the MODULE-IDENTITY value

The value of an invocation of the MODULE-IDENTITY macro is an OBJECT IDENTIFIER. As such, this value may be authoritatively used when referring to the information module containing the invocation. The ID is the official name tag ๐Ÿท๏ธ

5.8. Usage Example

Consider 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 "9210070433Z"
    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      "9210070433Z"
    DESCRIPTION
            "Initial version of this MIB module."
-- contact IANA for actual number
    ::= { experimental xx }


END

6. Mapping of the OBJECT-IDENTITY macro

okay so the OBJECT-IDENTITY macro is for defining info about an OBJECT IDENTIFIER assignment ๐Ÿฆ‹ It should be noted that the expansion of the OBJECT-IDENTITY macro is something which conceptually happens during implementation and not during run-time. Same vibe as before: build time, not run time ๐Ÿ™ˆ

6.1. Mapping of the STATUS clause

The STATUS clause, which must be present, indicates whether this definition is current or historic.

The values "current" and "obsolete" are self-explanatory ๐Ÿ’€

6.2. Mapping of the DESCRIPTION clause

The DESCRIPTION clause, which must be present, contains a textual description of the object assignment.

6.3. Mapping of the REFERENCE clause

The REFERENCE clause, which need not be present, contains a textual cross-reference to an object assignment defined in some other information module. It's like a "see also" that points to another 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

Consider 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 this one's the big one ๐Ÿ”ฅ The OBJECT-TYPE macro is used to define a managed object. It should be noted that the expansion of the OBJECT-TYPE macro is something which conceptually happens during implementation and not during run-time. Build time again, bestie โฑ๏ธ

7.1. Mapping of the SYNTAX clause

The SYNTAX clause, which must be present, defines the abstract data structure corresponding to that object. The data structure must be one of the alternatives defined in the ObjectSyntax CHOICE. So you pick from the ObjectSyntax menu ๐Ÿ“

Full ASN.1 sub-typing is allowed, as appropriate to the underlying ASN.1 type, primarily as an aid to implementors in understanding the meaning of the object. Any such restriction on size, range, enumerations or repertoire specified in this clause represents the maximal level of support which makes "protocol sense". Of course, sub-typing is not allowed for the Counter32 or Counter64 types, but is allowed for the Gauge32 type. Counters are a no-go for sub-typing, but Gauge32 is fair game ๐Ÿ™…โ€โ™€๏ธโœจ

The semantics of ObjectSyntax are now described. Let's go ๐Ÿ’–

7.1.1. Integer32 and INTEGER

The Integer32 type represents integer-valued information between -2^31 and 2^31-1 inclusive (-2147483648 to 2147483647 decimal). This type is indistinguishable from the INTEGER type. Same energy, different name tag ๐ŸŽ€

The INTEGER type may also be used to represent integer-valued information, if it contains named-number enumerations, or if it is sub-typed to be more constrained than the Integer32 type. In the former case, only those named-numbers so enumerated may be present as a value. Note that although 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, further, enumerated values needn't be contiguously assigned. So starting at 1 is the recommended vibe, but it's not a dealbreaker ๐ŸŒธ

Finally, the hyphen character is not allowed as a part of the label name for any named-number enumeration. No hyphens in those labels, periodt ๐Ÿšซ

7.1.2. OCTET STRING

The OCTET STRING type represents arbitrary binary or textual data. Although there is no SMI-specified size limitation for this type, MIB designers should realize that there may be implementation and interoperability limitations for sizes in excess of 255 octets. No official size cap, but past 255 octets things can get messy ๐Ÿ‘€

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). So up to 128 sub-IDs, and each one tops out at 4294967295 ๐Ÿงฎ

7.1.4. BIT STRING

The BIT STRING type represents an enumeration of named bits. This collection is assigned non-negative, contiguous values, starting at zero. Only those named-bits so enumerated may be present in a value.

A requirement on "standard" MIB modules is that the hyphen character is not allowed as a part of the label name for any named-bit enumeration. Hyphens are a no-go here too, bestie ๐Ÿ™…โ€โ™€๏ธ

7.1.5. IpAddress

The IpAddress type represents a 32-bit internet address. It is represented as an OCTET STRING of length 4, in network byte-order. So four octets, in network byte-order, slay ๐ŸŒ

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]. It's giving legacy, so for new stuff, use TEXTUAL-CONVENTION ๐Ÿ’…

7.1.6. Counter32

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. It goes up and up, then loops back to zero, like a lil odometer ๐Ÿš—

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-type using this ASN.1 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 a SYNTAX clause value of TimeStamp (a textual convention defined in [3]) indicating the time of the last discontinuity. So if the counter can reset at odd times, pair it with a TimeStamp so people know when the reset happened โฐ

The value of the MAX-ACCESS clause for objects with a SYNTAX clause value of Counter32 is always "read-only". Counters are read-only, always ๐Ÿ”’

A DEFVAL clause is not allowed for objects with a SYNTAX clause value of Counter32. No DEFVAL for Counter32, that's the rule ๐Ÿ™…โ€โ™€๏ธ

7.1.7. Gauge32

The Gauge32 type represents a non-negative integer, which 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 information being modeled is greater or equal to that maximum value; if the information being modeled subsequently decreases below the maximum value, the Gauge also decreases. Gauge32 goes up and down like a little thermometer ๐ŸŒก๏ธ but it caps out at the max and never goes past it โœจ

7.1.8. TimeTicks

The TimeTicks type is a non-negative integer that counts hundredths of a second, wrapping around at 2^32 (4294967296 decimal) ๐Ÿ•ฐ๏ธโœจ Basically a little stopwatch that resets at 2^32. The catch is that any object using TimeTicks has to say which reference epochs it's counting from. Your bestie needs to know the starting line ๐Ÿ’…

For example, [3] defines the TimeStamp textual convention, which is built on TimeTicks ๐Ÿฆ‹ For a TimeStamp, the first reference epoch is when MIB-II's sysUpTime [7] was zero, and the second is whatever sysUpTime currently reads ๐ŸŒธ

7.1.9. Opaque ๐ŸŽ€

Opaque is only here for backward compatibility ๐Ÿ™ˆ It SHALL NOT be used for newly-defined object types, so don't even think about it bestie ๐Ÿ’€

Opaque lets you smuggle in arbitrary ASN.1 syntax ๐Ÿงš The value gets encoded with the ASN.1 Basic Encoding Rules [4] into a string of octets, and then that string gets wrapped up as an OCTET STRING. It's literally a double wrap, like a present inside a present ๐ŸŽ

Quick note: a conforming implementation only has to be able to accept and recognize opaquely-encoded data ๐Ÿ’œ It does NOT have to unwrap the data and then make sense of what's inside, which is kind of a relief tbh ๐Ÿ˜ญ

A requirement on "standard" MIB modules is that no object MAY have a SYNTAX clause value of Opaque. ๐Ÿšซ

7.1.10. NsapAddress ๐ŸŒˆ

NsapAddress is how an OSI address gets represented as a variable-length OCTET STRING ๐ŸŒŠ The first octet is a binary value from 0..20 and tells you how many octets long the NSAP is. After that comes the NSAP itself in concrete binary notation, starting with the most significant octet ๐Ÿ’–

A zero-length NSAP is the special "default NSAP" ๐Ÿ‘‘ It's basically the NSAP version of 0.0.0.0. That one gets encoded as a single octet holding the value 0. Every other NSAP is encoded in at least 4 octets ๐Ÿ“

Lowkey a quirk alert: NsapAddress is a tagged type for historical reasons ๐Ÿ™ƒ Network addresses SHOULD be represented by invoking the TEXTUAL-CONVENTION macro [3] instead โœจ

7.1.11. Counter64 ๐Ÿ”ฅ

Counter64 is a non-negative integer that keeps going up until it hits its max of 2^64-1 (18446744073709551615 decimal) ๐Ÿš€ Then it wraps around and starts counting from zero again. Iconic behaviour, honestly ๐Ÿ’…

Counters don't have a defined "initial" value, so one single value of a Counter usually tells you basically nothing on its own ๐Ÿ™ˆ Discontinuities in the going-up pattern usually happen when the management system gets re-initialized, plus any other times the description of the object-type says so. If those other times can happen, for example when an object instance gets created at some random moment that isn't a re-initialization, then a matching object SHOULD be defined with a SYNTAX clause value of TimeStamp (a textual convention from [3]) that records when the last discontinuity happened โฐ

The MAX-ACCESS clause for objects with a SYNTAX clause value of Counter64 is always read-only. No edits, bestie ๐Ÿ”’

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 โณ Basically, only reach for Counter64 when Counter32 would wrap too fast to be useful ๐Ÿฆ‹

A DEFVAL clause is not allowed for objects with a SYNTAX clause value of Counter64 ๐Ÿ™…โ€โ™€๏ธ

7.1.12. UInteger32 ๐Ÿ’

UInteger32 is integer-valued info from 0 up to 2^32-1 inclusive (0 to 4294967295 decimal). Simple and sweet ๐Ÿซถ

7.2. Mapping of the UNITS clause ๐Ÿ“

The UNITS clause doesn't have to be there, but if you include it, it's a text description of what units the object is measured in ๐ŸŒธ

7.3. Mapping of the MAX-ACCESS clause ๐Ÿ”

The MAX-ACCESS clause MUST be present. It tells you whether it makes "protocol sense" to read, write and/or create an instance of the object ๐Ÿ’œ This is the maximum level of access the object gets. (That maximum is totally independent of any administrative authorization policy, so don't mix them up ๐Ÿ™ˆ)

The value read-write means read and write access make "protocol sense", but create doesn't. The value read-create means read, write and create all make "protocol sense" โœจ The value not-accessible is for either an auxiliary object (see Section 7.7) or an object that's only reachable through a notification (for example, snmpTrapOID [5]) ๐Ÿฆ‹

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

If any columnar object in a conceptual row has read-create as its maximal level of access, then no other columnar object in that same conceptual row may have a maximal access of read-write ๐Ÿšซ (Note that read-create is a superset of read-write, so it's like the bigger sibling who already does everything ๐Ÿ‘‘)

7.4. Mapping of the STATUS clause ๐Ÿšฆ

The STATUS clause MUST be present, and it says whether a definition is current or historic ๐Ÿ’…

The values current and obsolete are pretty self-explanatory ๐Ÿ’€ The deprecated value means the object is obsolete, but an implementor might want to keep supporting it so things stay interoperable with older implementations ๐Ÿค

7.5. Mapping of the DESCRIPTION clause ๐Ÿ“

The DESCRIPTION clause MUST be present. It's a text definition of the object that gives every semantic detail needed to implement it, and it SHOULD also hold any info that would otherwise live in ASN.1 commentary annotations attached to the object โœจ

7.6. Mapping of the REFERENCE clause ๐Ÿ”—

The REFERENCE clause doesn't have to be there. It's a text cross-reference to an object defined in some other information module ๐ŸŒˆ This comes in handy when you're de-osifying a MIB module that some other organization made ๐Ÿงš

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

The INDEX clause MUST be present if the object corresponds to a conceptual row (unless an AUGMENTS clause is there instead), and it MUST be absent otherwise ๐Ÿ™ƒ It defines the instance identification info for the columnar objects underneath that object ๐Ÿซถ

Here's the thing: management operations only ever apply to scalar objects ๐Ÿ”ข But management app developers love to picture the MIB as tables, so we pretend there are imaginary table structures over the ordered collection of objects ๐ŸŽ€ Each conceptual table holds zero or more rows, and each row can hold one or more scalar objects, which are called columnar objects ๐Ÿ’– This gets formalized by using the OBJECT-TYPE macro to define both an object for the table and an object for the row in that table ๐Ÿฆ‹

A conceptual table has SYNTAX of this form:

SEQUENCE OF <EntryType>

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

<EntryType>

where <EntryType> is a SEQUENCE type defined like this:

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

There's one <type> for each subordinate object, and each <type> looks like this:

<descriptor> <syntax>

Here <descriptor> is the descriptor naming a subordinate object, and <syntax> takes the value of that subordinate object's SYNTAX clause, optionally leaving out the sub-typing info ๐Ÿงฉ Also, these ASN.1 types are always present, since the DEFAULT and OPTIONAL clauses are disallowed in the SEQUENCE definition ๐Ÿšซ The MAX-ACCESS clause for conceptual tables and rows is not-accessible ๐Ÿ”’

For leaf objects that aren't columnar objects, instances get identified by appending a sub-identifier of zero to the object's name 0๏ธโƒฃ Otherwise, the INDEX clause of the conceptual row object above a columnar object defines the instance identification info ๐Ÿชช

The instance identification info in an INDEX clause MUST specify object(s) whose value(s) will uniquely tell apart each conceptual row ๐Ÿ’˜ The syntax of those objects shows how to build the instance identifier:

(1) Integer-valued: a single sub-identifier that takes the integer value (this only works for non-negative integers) ๐Ÿ”ข

(2) String-valued, fixed-length strings (or variable-length ones preceded by the IMPLIED keyword): n sub-identifiers, where n is the length of the string. Each octet of the string gets its own 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 then each octet of the string gets its own sub-identifier ๐ŸŒท

(4) Object identifier-valued: n+1 sub-identifiers, where n is the number of sub-identifiers in the value. The first sub-identifier is n itself, and then each sub-identifier in the value gets copied over ๐Ÿ“‹

(5) IpAddress-valued: 4 sub-identifiers, written in the familiar a.b.c.d notation ๐ŸŒ

(6) NsapAddress-valued: n sub-identifiers, where n is the length of the value. Each octet of the value gets its own sub-identifier ๐ŸŒŠ

Heads up: the IMPLIED keyword can only show up for objects with a variable-length syntax (like variable-length strings or object identifier-valued objects) ๐Ÿง It can appear at most once within the INDEX clause, and if it does, it's tied to the right-most object with a variable-length syntax ๐Ÿ‘‰ And you can't use IMPLIED on a variable-length string object if that string might have a zero-length value ๐Ÿšซ

Instances identified by integer-valued objects SHOULD be numbered starting from one (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 in the INDEX clause of a conceptual row and also columnar objects of that same row are called auxiliary objects ๐ŸŽ€ The MAX-ACCESS clause for newly-defined auxiliary objects is not-accessible. However, a conceptual row MUST contain at least one columnar object that isn't an auxiliary object (meaning the MAX-ACCESS clause for that object is either read-only or read-create) ๐Ÿซง

Okay that's the whole vibe, and the facts stay exactly as they were ๐Ÿ’š

Note that objects named in a conceptual row's INDEX clause don't have to be columnar objects of that same row ๐Ÿ‘€. When they aren't, the DESCRIPTION clause of the conceptual row must include a textual explanation of how those INDEX objects are used to uniquely identify instances of the row's columnar objects. Bestie, that explanation is not optional ๐Ÿ’…

7.7.1. Creation and Deletion of Conceptual Rows

For newly-defined conceptual rows that allow new object instances to be created and existing ones to be deleted, 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 called the status column for the conceptual row. It's giving control panel ๐ŸŽ›๏ธโœจ

7.8. Mapping of the AUGMENTS clause

The AUGMENTS clause is an alternative to the INDEX clause, and it must not be present unless the object corresponds to a conceptual row. Every object that corresponds to a conceptual row has either an INDEX clause or an AUGMENTS clause, so it's one or the other, never both ๐Ÿฆ‹

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 a conceptual row augmentation, and the AUGMENTS clause names the object for the base conceptual row that this conceptual row extension augments. Instances of subordinate columnar objects of a conceptual row extension are identified according to the INDEX clause of the base conceptual row for the object named in the AUGMENTS clause. They also exist under the same semantics as the subordinate columnar objects of the base conceptual row being augmented. So creating a base conceptual row implies the matching creation of any conceptual row augmentations ๐Ÿงš

For example, a MIB designer might want to add extra columns in an "enterprise-specific" MIB that logically extend a conceptual row in a "standard" MIB. The "standard" MIB would have the definition of the conceptual row with the INDEX clause, and the "enterprise-specific" MIB would define the conceptual row using the AUGMENTS clause.

A base conceptual row may be augmented by multiple conceptual row extensions, so one row can have a whole squad of augmentations ๐ŸŒˆ

7.8.1. Relation between INDEX and AUGMENTS clauses

When you're defining instance identification information for a conceptual table, pick the option that fits:

  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 which is identical to the one in the existing table.
  3. Otherwise, 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 is optional. It defines an acceptable default value that a SNMPv2 entity acting in an agent role may use, at its discretion, when an object instance is created ๐Ÿ“

When a conceptual row is created and an instance of a columnar object isn't included as one of the operands in the matching management protocol set operation, the DEFVAL clause (if present) gives an acceptable default value that a SNMPv2 entity acting in an agent role might use.

The value of the DEFVAL clause must, of course, match the SYNTAX clause for the object. If the value is an OBJECT IDENTIFIER, then it must be written as a single ASN.1 identifier, not as a collection of sub-identifiers. No cap, that's a big one ๐Ÿ™ˆ

If an operand to the management protocol set operation is an instance of a read-only object, the error `notWritable' [6] is returned. That's why the DEFVAL clause is handy: it can supply an acceptable default value that a SNMPv2 entity acting in an agent role might use instead ๐Ÿ’–

Here are some possible DEFVAL clauses, by example:

ObjectSyntax        DEFVAL clause
-----------------   ------------
Integer32           1
                    -- same for Gauge32, TimeTicks, UInteger32
INTEGER             valid -- enumerated value
OCTET STRING        'ffffffffffff'H
OBJECT IDENTIFIER   sysDescr
BIT STRING          { primary, secondary } -- enumerated values
      IpAddress           'c0210415'H -- 192.33.4.21

Object types with a SYNTAX of Counter32 or Counter64 may not have DEFVAL clauses, since they don't have defined initial values. However, it is recommended that they be initialized to zero. Zero is the comfy default here ๐Ÿงธ

7.10. Mapping of the OBJECT-TYPE value

The value of an OBJECT-TYPE macro invocation 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.
  3. Otherwise, no other OBJECT IDENTIFIERs which are subordinate to the object may be assigned.

The final sub-identifier of any administratively assigned name for an object shall be positive. A zero-valued final sub-identifier is reserved for future use, so hands off the zero ๐Ÿ™…โ€โ™€๏ธ

Also, even though conceptual tables and rows get administratively assigned names, the management protocol can't manipulate these conceptual objects in aggregate form. Individual instances only, babe ๐Ÿ‘‘

7.11. Usage Example

Let's look at how you might define a conceptual table and its subordinates ๐Ÿง

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 underCreation(1).  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 โœจ

okay so the NOTIFICATION-TYPE macro is how you define the info inside an unsolicited message of management info ๐Ÿ“จ (so either a SNMPv2-Trap-PDU or an InformRequest-PDU). lowkey the key thing: expanding this macro happens conceptually during implementation, NOT at run-time ๐Ÿซถ

8.1. Mapping of the OBJECTS clause

the OBJECTS clause is optional ๐ŸŒธ it defines the ordered list of MIB objects that get included in every instance of the notification. ordering matters, bestie ๐Ÿ’…

8.2. Mapping of the STATUS clause

the STATUS clause must be present โœจ and it tells you whether the definition is current or historic.

"current" and "obsolete" are pretty self-explanatory ๐Ÿ’– but "deprecated" is the spicy one: it means the notification is obsolete, BUT an implementor may still want to support it so it plays nicely with older implementations ๐Ÿงš

8.3. Mapping of the DESCRIPTION clause

the DESCRIPTION clause must be present ๐ŸŽ€ this is the textual definition of the notification, and it should give every semantic detail needed for implementing it. anything that would otherwise go in ASN.1 commentary annotations should live here instead ๐ŸŒˆ

the big one: the DESCRIPTION clause should document which instances of the objects listed in the OBJECTS clause should be included in notifications of this type ๐Ÿ”ฅ

8.4. Mapping of the REFERENCE clause

the REFERENCE clause is optional ๐Ÿ“š it's a textual cross-reference to a notification defined in some other information module. super useful when you're de-osifying a MIB module that some other organization made ๐Ÿฆ‹

8.5. Mapping of the NOTIFICATION-TYPE value

the value of a NOTIFICATION-TYPE invocation is the name of the notification ๐Ÿท๏ธ it's an OBJECT IDENTIFIER, an administratively assigned name.

Sections 4.2.6 and 4.2.7 of [6] explain how NOTIFICATION-TYPE gets used to generate a SNMPv2-Trap-PDU or an InformRequest-PDU, respectively ๐Ÿ“

8.6. Usage Example

let's look at how a linkUp trap could 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 }

so with this invocation, the trap authoritatively identified as

{ snmpTraps 4 }

is what gets used to report a link coming up ๐Ÿฆ‹

and ngl, this is so cool: a SNMPv2 entity acting in an agent role can be configured to send this trap to zero or more SNMPv2 entities acting in a manager role ๐Ÿ’œ it all depends on the contents of the aclTable and viewTable [8] tables. for example, with a smart use of the viewTable, an agent could send ALL linkUp traps to one particular SNMPv2 entity, and only the linkUp traps for certain interfaces to other entities. main character energy ๐Ÿ‘‘๐Ÿซถ


9. Refined Syntax

some macros let you refine an object's syntax (like the SYNTAX clause in the MODULE-COMPLIANCE macro [2]) ๐ŸŽ€ but not every refinement is valid, bestie ๐Ÿ™ˆ in particular, the object's primitive or application type must not be changed. no swapping types, periodt ๐Ÿ’…

on top of that, these restrictions apply:

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

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;
  • (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 ๐Ÿ™…โ€โ™€๏ธ

one more thing: when you refine an object whose SYNTAX clause value is Integer32 or UInteger32, the refined SYNTAX gets expressed as an INTEGER, and the restrictions in the table above apply ๐Ÿ”ขโœจ


10. Extending an Information Module

okay so once people are using a published information module, it might be a good idea to revise it ๐ŸŒˆ that's totally normal!

first step: 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 REVISION and DESCRIPTION pair of clauses. other existing clauses in the invocation can be updated too ๐Ÿงš

and the module's label (like "FIZBIN-MIB" from the example in Section 5.8) does NOT change when the information module is revised ๐Ÿซถ same name, new glow-up.

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. no shortcuts, bestie ๐Ÿ™…โ€โ™€๏ธ

10.2. Object Definitions

an object definition can be revised in any of these 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 are changed (so if a non-editorial change is made to any clause other than those specifically allowed above), then the OBJECT IDENTIFIER value for that object must also change ๐Ÿ’€

note that changing the descriptor of an existing object counts as a semantic change, because those strings may be used in an IMPORTS statement ๐Ÿ“

finally, if an object's STATUS clause value changes, then its DESCRIPTION clause should be updated to match ๐ŸŒธ

10.3. Notification Definitions

a notification definition can be revised in this way ๐ŸŽ€

  • (1) a REFERENCE clause may be added or updated.

otherwise, if the semantics of any previously defined notification are changed (so if a non-editorial change is made to any clause other than those specifically allowed above), then the OBJECT IDENTIFIER value for that notification must also change ๐Ÿ’…

changing the descriptor of an existing notification is a semantic change too, since these strings may be used in an IMPORTS statement ๐Ÿซถ

and finally: if an object's STATUS clause value changes, then its DESCRIPTION clause should be updated accordingly โœจ

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

okay so there's been a growing pile of work lately on taking MIBs that other orgs already defined (like the IEEE ๐Ÿงš) and de-OSIfying them so they work with the Internet-standard network management framework. The steps are straightforward, just tedious ๐Ÿ’…. It helps a lot if you've already written MIB modules for that framework before.

The first step is to build a skeletal MIB module, like the one shown earlier in Section 5.8 ๐Ÿฆ‹. Next, you sort the objects into groups. Optional objects are not permitted, so when you make the MIB module, the optional objects have to go into additional groups. If you implement one of those groups, you have to implement every object in it ๐Ÿซถ. For the first pass, it's wisest to just ignore any 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 objects later if experience says you need them ๐ŸŒธ.


11.1. Managed Object Mapping ๐Ÿ’–

Next, for each managed object class, figure out whether there can be multiple instances of that class. If not, then for each of its attributes, use the OBJECT-type macro to make an equivalent definition โœจ.

If there can be multiple instances, then define a conceptual table with conceptual rows. Each row holds a columnar object for each of the managed object class's attributes ๐ŸŽ€. If the managed object class sits inside the containment tree of another managed object class, you usually need an object 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 define a conceptual row, think about how network management operations will act on its columnar objects, because that's how you optimize things ๐Ÿ‘‘. The big thing is to avoid putting more columnar objects in one conceptual row than can fit in a single PDU. As a rule of thumb, a conceptual row should hold no more than about 20 objects. Relatedly, (or as a way to follow the "20 object guideline") you should group columnar objects into tables based on how network management operations are expected to group them. So the contents of a conceptual row should match typical access patterns. You can organize them by function, like one row for statistics and another for parameters, or by usage, like commonly-needed objects versus rarely-needed ones ๐Ÿ“.

On the flip side, you should also avoid defining conceptual rows where the number of columnar objects used as indexes is bigger than the number used to hold information ๐Ÿ™ˆ. And don't split a managed object class's attributes across lots 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-go ๐Ÿ’€.

11.1.1. Mapping to the SYNTAX clause ๐Ÿง

When you map 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. It takes any of the given values that can be represented with an Integer32.

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

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

(6) A non-tabular object with a complex syntax, like REAL or EXTERNAL, has to be decomposed, usually into an OCTET STRING (if that makes sense). As a rule, any object with a complicated syntax should be avoided ๐Ÿ™ƒ.

(7) Tabular objects have to 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, and 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 get 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 being mapped. If it can, define the DEFVAL clause to match ๐ŸŒธ.


11.2. Action Mapping ๐ŸŽฌ

Actions are modeled as read-write objects, where writing a particular value causes a state change. (Usually, as part of that state change, some action might happen 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 also usually 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: just copy the text, and sanitize any embedded double quotation marks (swap them for 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 in that document ๐Ÿฆ‹.


11.3. Event Mapping ๐Ÿ””

Events are 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: just copy the text, and sanitize any embedded double quotation marks (swap them for 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 in that document ๐ŸŽ€.

12. Acknowledgements ๐Ÿ™โœจ

okay so the object definitions section (and the MIB de-osification bit ๐Ÿงน) is based, in part, on RFCs 1155 and 1212 ๐Ÿ’…. The IMPLIED keyword came from a convo with David T. Perkins in December, 1991 ๐Ÿซถ.

The trap definitions section is based, in part, on RFC 1215 ๐Ÿ””.

And the SNMP version 2 working group gets a huge thank you for their comments ๐Ÿ’– (they were absolutely iconic):

     Beth Adams, Network Management Forum
     Steve Alexander, INTERACTIVE Systems Corporation
     David Arneson, Cabletron Systems
     Toshiya Asaba
     Fred Baker, ACC
     Jim Barnes, Xylogics, Inc.
     Brian Bataille
     Andy Bierman, SynOptics Communications, Inc.
     Uri Blumenthal, IBM Corporation
     Fred Bohle, Interlink
     Jack Brown
     Theodore Brunner, Bellcore
     Stephen F. Bush, GE Information Services
     Jeffrey D. Case, University of Tennessee, Knoxville
     John Chang, IBM Corporation
     Szusin Chen, Sun Microsystems
     Robert Ching
     Chris Chiotasso, Ungermann-Bass
     Bobby A. Clay, NASA/Boeing
     John Cooke, Chipcom
     Tracy Cox, Bellcore
     Juan Cruz, Datability, Inc.
     David Cullerot, Cabletron Systems
     Cathy Cunningham, Microcom
     James R. (Chuck) Davin, Bellcore
     Michael Davis, Clearpoint
     Mike Davison, FiberCom
     Cynthia DellaTorre, MITRE
     Taso N. Devetzis, Bellcore
     Manual Diaz, DAVID Systems, Inc.
     Jon Dreyer, Sun Microsystems
     David Engel, Optical Data Systems
     Mike Erlinger, Lexcel
     Roger Fajman, NIH
     Daniel Fauvarque, Sun Microsystems
     Karen Frisa, CMU
     Shari Galitzer, MITRE
     Shawn Gallagher, Digital Equipment Corporation
     Richard Graveman, Bellcore
     Maria Greene, Xyplex, Inc.
     Michel Guittet, Apple
     Robert Gutierrez, NASA
     Bill Hagerty, Cabletron Systems
     Gary W. Haney, Martin Marietta Energy Systems
     Patrick Hanil, Nokia Telecommunications
     Matt Hecht, SNMP Research, Inc.
     Edward A. Heiner, Jr., Synernetics Inc.
     Susan E. Hicks, Martin Marietta Energy Systems
     Geral Holzhauer, Apple
     John Hopprich, DAVID Systems, Inc.
     Jeff Hughes, Hewlett-Packard
     Robin Iddon, Axon Networks, Inc.
     David Itusak
     Kevin M. Jackson, Concord Communications, Inc.
     Ole J. Jacobsen, Interop Company
     Ronald Jacoby, Silicon Graphics, Inc.
     Satish Joshi, SynOptics Communications, Inc.
     Frank Kastenholz, FTP Software
     Mark Kepke, Hewlett-Packard
     Ken Key, SNMP Research, Inc.
     Zbiginew Kielczewski, Eicon
     Jongyeoi Kim
     Andrew Knutsen, The Santa Cruz Operation
     Michael L. Kornegay, VisiSoft
     Deirdre C. Kostik, Bellcore
     Cheryl Krupczak, Georgia Tech
     Mark S. Lewis, Telebit
     David Lin
     David Lindemulder, AT&T/NCR
     Ben Lisowski, Sprint
     David Liu, Bell-Northern Research
     John Lunny, The Wollongong Group
     Robert C. Lushbaugh Martin, Marietta Energy Systems
     Michael Luufer, BBN
     Carl Madison, Star-Tek, Inc.
     Keith McCloghrie, Hughes LAN Systems
     Evan McGinnis, 3Com Corporation
     Bill McKenzie, IBM Corporation
     Donna McMaster, SynOptics Communications, Inc.
     John Medicke, IBM Corporation
     Doug Miller, Telebit
     Dave Minnich, FiberCom
     Mohammad Mirhakkak, MITRE
     Rohit Mital, Protools
     George Mouradian, AT&T Bell Labs
     Patrick Mullaney, Cabletron Systems
     Dan Myers, 3Com Corporation
     Rina Nathaniel, Rad Network Devices Ltd.
     Hien V. Nguyen, Sprint
     Mo Nikain
     Tom Nisbet
     William B. Norton, MERIT
     Steve Onishi, Wellfleet Communications, Inc.
     David T. Perkins, SynOptics Communications, Inc.
     Carl Powell, BBN
     Ilan Raab, SynOptics Communications, Inc.
     Richard Ramons, AT&T
     Venkat D. Rangan, Metric Network Systems, Inc.
     Louise Reingold, Sprint
     Sam Roberts, Farallon Computing, Inc.
     Kary Robertson, Concord Communications, Inc.
     Dan Romascanu, Lannet Data Communications Ltd.
     Marshall T. Rose, Dover Beach Consulting, Inc.
     Shawn A. Routhier, Epilogue Technology Corporation
     Chris Rozman
     Asaf Rubissa, Fibronics
     Jon Saperia, Digital Equipment Corporation
     Michael Sapich
     Mike Scanlon, Interlan
     Sam Schaen, MITRE
     John Seligson, Ultra Network Technologies
     Paul A. Serice, Corporation for Open Systems
     Chris Shaw, Banyan Systems
     Timon Sloane
     Robert Snyder, Cisco Systems
     Joo Young Song
     Roy Spitier, Sprint
     Einar Stefferud, Network Management Associates
     John Stephens, Cayman Systems, Inc.
     Robert L. Stewart, Xyplex, Inc. (chair)
     Kaj Tesink, Bellcore
     Dean Throop, Data General
     Ahmet Tuncay, France Telecom-CNET
     Maurice Turcotte, Racal Datacom
     Warren Vik, INTERACTIVE Systems Corporation
     Yannis Viniotis
     Steven L. Waldbusser, Carnegie Mellon Universitty
     Timothy M. Walden, ACC
     Alice Wang, Sun Microsystems
     James Watt, Newbridge
     Luanne Waul, Timeplex
     Donald E. Westlake III, Digital Equipment Corporation
     Gerry White
     Bert Wijnen, IBM Corporation
     Peter Wilson, 3Com Corporation
     Steven Wong, Digital Equipment Corporation
     Randy Worzella, IBM Corporation
     Daniel Woycke, MITRE
     Honda Wu
     Jeff Yarnell, Protools
     Chris Young, Cabletron
     Kiho Yum, 3Com Corporation

13. References ๐Ÿ“š

okay here are the receipts ๐Ÿงพ๐Ÿค“ (every single one, no cap):

  • [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] Case, J., McCloghrie, K., Rose, M., and Waldbusser, S., "Conformance Statements for version 2 of the the Simple Network Management Protocol (SNMPv2)", RFC 1444, SNMP Research, Inc., Hughes LAN Systems, Dover Beach Consulting, Inc., Carnegie Mellon University, April 1993.
  • [3] Case, J., McCloghrie, K., Rose, M., and Waldbusser, S., "Textual Conventions for version 2 of the the Simple Network Management Protocol (SNMPv2)", RFC 1443, SNMP Research, Inc., Hughes LAN Systems, Dover Beach Consulting, Inc., Carnegie Mellon University, April 1993.
  • [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] Case, J., McCloghrie, K., Rose, M., and Waldbusser, S., "Management Information Base for version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1450, SNMP Research, Inc., Hughes LAN Systems, Dover Beach Consulting, Inc., Carnegie Mellon University, April 1993.
  • [6] Case, J., McCloghrie, K., Rose, M., and Waldbusser, S., "Protocol Operations for version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1448, SNMP Research, Inc., Hughes LAN Systems, Dover Beach Consulting, Inc., Carnegie Mellon University, April 1993.
  • [7] McCloghrie, K., and Rose, M., "Management Information Base for Network Management of TCP/IP-based internets: MIB-II", STD 17, RFC 1213, March 1991.
  • [8] McCloghrie, K., and Galvin, J., "Party MIB for version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1447, Hughes LAN Systems, Trusted Information Systems, April 1993.

14. Security Considerations ๐Ÿ”’๐Ÿ’€

Security issues are not discussed in this memo. ๐Ÿ˜ญ no cap, that's the whole section, so handle it with care and check the other RFCs in the reference list for their security stories ๐Ÿซถ

15. Authors' Addresses ๐Ÿ’Œ

these are the lovely people who wrote it ๐Ÿงšโœจ

Jeffrey D. Case
SNMP Research, Inc.
3001 Kimberlin Heights Rd.
Knoxville, TN  37920-9716
US

Phone: +1 615 573 1434
Email: case@snmp.com


Keith McCloghrie
Hughes LAN Systems
1225 Charleston Road
Mountain View, CA  94043
US

Phone: +1 415 966 7934
Email: kzm@hls.com


Marshall T. Rose
Dover Beach Consulting, Inc.
420 Whisman Court
Mountain View, CA  94043-2186
US

Phone: +1 415 968 1052
Email: mrose@dbc.mtview.ca.us

Steven Waldbusser
Carnegie Mellon University
4910 Forbes Ave
Pittsburgh, PA  15213
US

Phone: +1 412 268 6628
Email: waldbusser@cmu.edu
๐Ÿ“ฆ where this page comes from