RFC-1212(7)

✨ RFC-1212(7) β€” MIB, and yes we're reading the whole thing ✨

okay so bestie, you're in the MIB manual, section 7, and the page is RFC-1212. that's the title. short, sweet, iconic. πŸ’…

and what even is it? it's an ASN.1 module β€” one big DEFINITIONS ::= BEGIN ... END that defines the OBJECT-TYPE macro. the entire page is that macro grammar laid out production by production, plus one little IndexSyntax CHOICE at the bottom. no prose paragraphs, no flags, no exit codes, no signals, no environment variables. just grammar. and we're reading every single line of it because nothing gets skipped on my watch. πŸ˜€πŸ’–


🌸 RFC-1212 DEFINITIONS ::= BEGIN 🌸

the module opens like this, and right up top it pulls in two things from its friends:

RFC-1212 DEFINITIONS ::= BEGIN

IMPORTS
    ObjectName
        FROM RFC1155-SMI
    DisplayString
        FROM RFC1158-MIB;

so the IMPORTS situation is:

  • ObjectName β€” coming in FROM RFC1155-SMI
  • DisplayString β€” coming in FROM RFC1158-MIB

that's the imports. done. slay. πŸŽ€


🧚 OBJECT-TYPE MACRO ::= BEGIN 🧚

here's the main character πŸ’«:

OBJECT-TYPE MACRO ::=
BEGIN
    TYPE NOTATION ::=
                                -- must conform to
                                -- RFC1155's ObjectSyntax
                      "SYNTAX" type(ObjectSyntax)
                      "ACCESS" Access
                      "STATUS" Status
                      DescrPart
                      ReferPart
                      IndexPart
                      DefValPart
    VALUE NOTATION ::= value (VALUE ObjectName)

🫢 TYPE NOTATION

it wants a "SYNTAX" that's type(ObjectSyntax) β€” and heads up, per the comment sitting right there in the source, it must conform to RFC1155's ObjectSyntax. then "ACCESS" Access, then "STATUS" Status, then the four trailing parts in exactly this order: DescrPart, ReferPart, IndexPart, DefValPart. order matters, periodt. ✨

πŸ‘‘ VALUE NOTATION

value (VALUE ObjectName). literally that. nothing more, nothing less, no notes.


πŸ” Access πŸ”

pick exactly one, bestie, no mixing and matching:

  • "read-only"
  • "read-write"
  • "write-only"
  • "not-accessible"
    Access ::= "read-only"
                    | "read-write"
                    | "write-only"
                    | "not-accessible"

🏷️ Status 🏷️

also one-of-four, and this is the whole lifecycle vibe right here:

  • "mandatory"
  • "optional"
  • "obsolete"
  • "deprecated"
    Status ::= "mandatory"
                    | "optional"
                    | "obsolete"
                    | "deprecated"

πŸ’Œ DescrPart πŸ’Œ

either you write a "DESCRIPTION" holding a value (description DisplayString), or you leave it empty. there is no third option, iykyk.

    DescrPart ::=
               "DESCRIPTION" value (description DisplayString)
                    | empty

πŸ“Ž ReferPart πŸ“Ž

same energy, different keyword: a "REFERENCE" holding a value (reference DisplayString), or empty.

    ReferPart ::=
               "REFERENCE" value (reference DisplayString)
                    | empty

πŸ“ IndexPart πŸ“

this is the spicy one, so listen up 🫢 β€” you either hand over an "INDEX" list wrapped in curly braces, or you say empty:

    IndexPart ::=
               "INDEX" "{" IndexTypes "}"
                    | empty
    IndexTypes ::=
               IndexType | IndexTypes "," IndexType

so IndexTypes is one IndexType, or a whole bunch of IndexTypes glued together with ",". comma-separated gang, we love to see it. 🌈

and here's IndexType with both of its inline comments, because they genuinely matter:

    IndexType ::=
                        -- if indexobject, use the SYNTAX
                        -- value of the correspondent
                        -- OBJECT-TYPE invocation
               value (indexobject ObjectName)
                        -- otherwise use named SMI type
                        -- must conform to IndexSyntax below
                    | type (indextype)

so: if it's an indexobject, use the SYNTAX value of the correspondent OBJECT-TYPE invocation. otherwise use a named SMI type β€” and that one must conform to IndexSyntax below. the source literally says "below". don't skip it. πŸ’€


🎁 DefValPart 🎁

last piece of the macro: a "DEFVAL" in curly braces holding a value (defvalue ObjectSyntax), or empty.

    DefValPart ::=
               "DEFVAL" "{" value (defvalue ObjectSyntax) "}"
                    | empty
   END
ok so that END closes out the macro, and yes, it has three spaces of indent in the source. we respect it exactly as it is. πŸ’…

πŸ”’ IndexSyntax ::= β€” the CHOICE era πŸ”’

here's the whole production, and then I'm breaking the choices down for you because there are five and one of them is INTEGER (0..MAX):

IndexSyntax ::=
    CHOICE {
        number
            INTEGER (0..MAX),
        string
            OCTET STRING,
        object
            OBJECT IDENTIFIER,
        address
            NetworkAddress,
        ipAddress
            IpAddress
    }

END

so the CHOICE gives you exactly these five options:

  • number β†’ INTEGER (0..MAX)
  • string β†’ OCTET STRING
  • object β†’ OBJECT IDENTIFIER
  • address β†’ NetworkAddress
  • ipAddress β†’ IpAddress

and then that final END shuts the entire module down. boom, curtain, we're out. πŸŽ‰


and that's the whole page, bestie β€” every production, every alternative, every inline comment, every empty, suffixed with our final END. not a single line dropped. πŸ’–

this one shipped to you in the Erlang/OTP SNMP docs β€” that's the source and the manual tag in the footer β€” on page RFC-1212(7). no date on this one, so I'm not inventing one. 🫢✨

πŸ“¦ where this page comes from