RFC 2579

Textual Conventions for SMIv2

๐Ÿ“… published April 1999, from ietf

Textual Conventions for SMIv2 ๐ŸŽ€

Okay bestie, the title block first ๐Ÿ’… This is RFC 2579, published in April 1999 by the Network Working Group. It's a Standards Track doc, tagged STD 58 โœจ, and it obsoletes RFC 1903. It doesn't update anything. The current editors are K. McCloghrie (Cisco Systems), D. Perkins (SNMPinfo), and J. Schoenwaelder (TU Braunschweig). The previous version was written by J. Case (SNMP Research), K. McCloghrie (Cisco Systems), M. Rose (First Virtual Holdings), and S. Waldbusser (International Network Services) ๐Ÿซถ


Status of this Memo ๐Ÿ“Œ

This doc specifies an Internet standards track protocol for the Internet community, and it's asking for discussion and suggestions for improvements ๐ŸŒธ For the standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited โœจ

Copyright (C) The Internet Society (1999). All Rights Reserved. ๐Ÿ’œ


Table of Contents ๐Ÿ—‚๏ธ

   1 Introduction ..................................................2
   1.1 A Note on Terminology .......................................2
   2 Definitions ...................................................2
   3 Mapping of the TEXTUAL-CONVENTION macro ......................20
   3.1 Mapping of the DISPLAY-HINT clause .........................21
   3.2 Mapping of the STATUS clause ...............................22
   3.3 Mapping of the DESCRIPTION clause ..........................23
   3.4 Mapping of the REFERENCE clause ............................23
   3.5 Mapping of the SYNTAX clause ...............................23
   4 Sub-typing of Textual Conventions ............................23
   5 Revising a Textual Convention Definition .....................23
   6 Security Considerations ......................................24
   7 Editors' Addresses ...........................................25
   8 References ...................................................25
   9 Full Copyright Statement .....................................26

1. Introduction ๐Ÿฆ‹

Okay so, management information is viewed as a collection of managed objects, all living in a virtual information store called the Management Information Base (MIB) ๐Ÿ—‚๏ธ Related objects get grouped together into MIB modules. These modules are written in an adapted subset of OSI's Abstract Syntax Notation One, ASN.1 (1988) [1], which is termed the Structure of Management Information (SMI) [2] โœจ

When you're designing a MIB module, it's super useful to make up new types that look like the ones in the SMI. Compared to an SMI type, each of these new types has a different name and a similar syntax, but a more precise semantics ๐Ÿ’– They're called textual conventions, and they exist for the convenience of humans reading the MIB module. This doc is where the initial set of textual conventions available to all MIB modules gets defined ๐ŸŽ€

Objects defined using a textual convention are always encoded using the rules that define their primitive type. Textual conventions do often come with special semantics though, so an ASN.1 macro, TEXTUAL-CONVENTION, is used to concisely convey the syntax and semantics of a textual convention ๐Ÿงš

1.1. A Note on Terminology ๐Ÿ“–

For the purpose of exposition, the original Structure of Management Information, as described in RFCs 1155 (STD 16), 1212 (STD 16), and RFC 1215, is termed the SMI version 1 (SMIv1). The current version of the Structure of Management Information is termed SMI version 2 (SMIv2) ๐Ÿ’…


2. Definitions ๐Ÿ“œ

SNMPv2-TC DEFINITIONS ::= BEGIN

IMPORTS
    TimeTicks         FROM SNMPv2-SMI;


-- definition of textual conventions

TEXTUAL-CONVENTION MACRO ::=
BEGIN
    TYPE NOTATION ::=
                  DisplayPart
                  "STATUS" Status
                  "DESCRIPTION" Text
                  ReferPart
                  "SYNTAX" Syntax

    VALUE NOTATION ::=
                   value(VALUE Syntax)      -- adapted ASN.1

    DisplayPart ::=
                  "DISPLAY-HINT" Text
                | empty

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

    ReferPart ::=
                  "REFERENCE" Text
                | empty

    -- a character string as defined in [2]
    Text ::= value(IA5String)

    Syntax ::=   -- Must be one of the following:
                       -- a base type (or its refinement), or
                       -- a BITS pseudo-type
                  type
                | "BITS" "{" NamedBits "}"

    NamedBits ::= NamedBit
                | NamedBits "," NamedBit

    NamedBit ::=  identifier "(" number ")" -- number is nonnegative

END




DisplayString ::= TEXTUAL-CONVENTION
    DISPLAY-HINT "255a"
    STATUS       current
    DESCRIPTION
            "Represents textual information taken from the NVT ASCII
            character set, as defined in pages 4, 10-11 of RFC 854.

            To summarize RFC 854, the NVT ASCII repertoire specifies:

              - the use of character codes 0-127 (decimal)

              - the graphics characters (32-126) are interpreted as
                US ASCII

              - NUL, LF, CR, BEL, BS, HT, VT and FF have the special
                meanings specified in RFC 854

              - the other 25 codes have no standard interpretation

              - the sequence 'CR LF' means newline

              - the sequence 'CR NUL' means carriage-return

              - an 'LF' not preceded by a 'CR' means moving to the
                same column on the next line.

              - the sequence 'CR x' for any x other than LF or NUL is
                illegal.  (Note that this also means that a string may
                end with either 'CR LF' or 'CR NUL', but not with CR.)

            Any object defined using this syntax may not exceed 255
            characters in length."
    SYNTAX       OCTET STRING (SIZE (0..255))

PhysAddress ::= TEXTUAL-CONVENTION
    DISPLAY-HINT "1x:"
    STATUS       current
    DESCRIPTION
            "Represents media- or physical-level addresses."
    SYNTAX       OCTET STRING


MacAddress ::= TEXTUAL-CONVENTION
    DISPLAY-HINT "1x:"
    STATUS       current
    DESCRIPTION
            "Represents an 802 MAC address represented in the
            `canonical' order defined by IEEE 802.1a, i.e., as if it
            were transmitted least significant bit first, even though
            802.5 (in contrast to other 802.x protocols) requires MAC
            addresses to be transmitted most significant bit first."
    SYNTAX       OCTET STRING (SIZE (6))

TruthValue ::= TEXTUAL-CONVENTION
    STATUS       current
    DESCRIPTION
            "Represents a boolean value."
    SYNTAX       INTEGER { true(1), false(2) }

TestAndIncr ::= TEXTUAL-CONVENTION
    STATUS       current
    DESCRIPTION
            "Represents integer-valued information used for atomic
            operations.  When the management protocol is used to specify
            that an object instance having this syntax is to be
            modified, the new value supplied via the management protocol
            must precisely match the value presently held by the
            instance.  If not, the management protocol set operation
            fails with an error of `inconsistentValue'.  Otherwise, if
            the current value is the maximum value of 2^31-1 (2147483647
            decimal), then the value held by the instance is wrapped to
            zero; otherwise, the value held by the instance is
            incremented by one.  (Note that regardless of whether the
            management protocol set operation succeeds, the variable-
            binding in the request and response PDUs are identical.)

            The value of the ACCESS clause for objects having this
            syntax is either `read-write' or `read-create'.  When an
            instance of a columnar object having this syntax is created,
            any value may be supplied via the management protocol.

            When the network management portion of the system is re-
            initialized, the value of every object instance having this
            syntax must either be incremented from its value prior to
            the re-initialization, or (if the value prior to the re-
            initialization is unknown) be set to a pseudo-randomly
            generated value."
    SYNTAX       INTEGER (0..2147483647)

AutonomousType ::= TEXTUAL-CONVENTION
    STATUS       current
    DESCRIPTION
            "Represents an independently extensible type identification
            value.  It may, for example, indicate a particular sub-tree
            with further MIB definitions, or define a particular type of
            protocol or hardware."
    SYNTAX       OBJECT IDENTIFIER


InstancePointer ::= TEXTUAL-CONVENTION
    STATUS       obsolete
    DESCRIPTION
            "A pointer to either a specific instance of a MIB object or
            a conceptual row of a MIB table in the managed device.  In
            the latter case, by convention, it is the name of the
            particular instance of the first accessible columnar object
            in the conceptual row.

            The two uses of this textual convention are replaced by
            VariablePointer and RowPointer, respectively."
    SYNTAX       OBJECT IDENTIFIER


VariablePointer ::= TEXTUAL-CONVENTION
    STATUS       current
    DESCRIPTION
            "A pointer to a specific object instance.  For example,
            sysContact.0 or ifInOctets.3."
    SYNTAX       OBJECT IDENTIFIER


RowPointer ::= TEXTUAL-CONVENTION
    STATUS       current
    DESCRIPTION
            "Represents a pointer to a conceptual row.  The value is the
            name of the instance of the first accessible columnar object
            in the conceptual row.

            For example, ifIndex.3 would point to the 3rd row in the
            ifTable (note that if ifIndex were not-accessible, then
            ifDescr.3 would be used instead)."
    SYNTAX       OBJECT IDENTIFIER
RowStatus ::= TEXTUAL-CONVENTION
    STATUS       current

okay bestie, RowStatus is the TC that runs the whole creation-and-deletion show for conceptual rows ๐ŸŽ€ It's the SYNTAX for the status column of a conceptual row (see Section 7.7.1 of [2].) and that column has six defined values โœจ

  • active ๐Ÿฆ‹ means the row is ready to use by the managed device
  • notInService ๐Ÿ’ค means the row exists in the agent but isn't usable yet. This one says nothing about whether the row is internally consistent, whether resources are available, or whether it matches the device's current state (see NOTE below) ๐Ÿ™ˆ
  • notReady ๐Ÿฅบ means the row exists, but it's missing info it needs to be usable. One or more required columns haven't been instantiated yet
  • createAndGo ๐Ÿš€ is what a management station sends to make a brand new instance AND have it auto-set to active, so it's ready to go immediately
  • createAndWait โณ is the same vibe as createAndGo, except the new instance does NOT get made available for use by the managed device
  • destroy ๐Ÿ’€ is sent by a management station that wants to delete every instance tied to an existing conceptual row

Okay so here's the tea ๐Ÿต Five of the six values (everything except notReady) can be sent in a management protocol set operation. But retrieval only ever gives back three values: notReady, notInService or active ๐Ÿ‘‘ When you query a row, it's in one of three states:

  • it's active (ready to use)
  • it's notInService, so not usable right now, but the agent has enough info to try making it usable
  • it's notReady, so not usable, AND trying to make it usable would fail because the agent doesn't have enough info (the state column has value notReady)

NOTE WELL ๐ŸŒˆ

This textual convention can be used for a MIB table whether or not its rows can be changed while they're active, or whether they have to be taken out of service first ๐Ÿ’… So it's on the DESCRIPTION clause of the status column to say whether the status column must not be active for some other column in the same row to be changed. If that's specified, the affected columns can be changed by an SNMP set PDU as long as the RowStatus wouldn't be equal to active either right before or right after processing the PDU. Put simply: if the same PDU also has a varbind that changes the RowStatus value, the column can be changed if RowStatus wasn't active when the PDU came in, OR if the varbind sets the status to something other than 'active' โœจ

Also, lowkey important ๐Ÿซถ whenever any elements of a row exist, the RowStatus column must also exist.

Here's the big picture, so the state diagram is the chart you want to screenshot ๐Ÿ“ธ It shows what happens when you apply each action to each state:

                                         STATE
              +--------------+-----------+-------------+-------------
              |      A       |     B     |      C      |      D
              |              |status col.|status column|
              |status column |    is     |      is     |status column
    ACTION    |does not exist|  notReady | notInService|  is active
--------------+--------------+-----------+-------------+-------------
set status    |noError    ->D|inconsist- |inconsistent-|inconsistent-
column to     |       or     |   entValue|        Value|        Value
createAndGo   |inconsistent- |           |             |
              |         Value|           |             |
--------------+--------------+-----------+-------------+-------------
set status    |noError  see 1|inconsist- |inconsistent-|inconsistent-
column to     |       or     |   entValue|        Value|        Value
createAndWait |wrongValue    |           |             |
--------------+--------------+-----------+-------------+-------------
set status    |inconsistent- |inconsist- |noError      |noError
column to     |         Value|   entValue|             |
active        |              |           |             |
              |              |     or    |             |
              |              |           |             |
              |              |see 2   ->D|see 8     ->D|          ->D
--------------+--------------+-----------+-------------+-------------
set status    |inconsistent- |inconsist- |noError      |noError   ->C
column to     |         Value|   entValue|             |
notInService  |              |           |             |
              |              |     or    |             |      or
              |              |           |             |
              |              |see 3   ->C|          ->C|see 6
--------------+--------------+-----------+-------------+-------------
set status    |noError       |noError    |noError      |noError   ->A
column to     |              |           |             |      or
destroy       |           ->A|        ->A|          ->A|see 7
--------------+--------------+-----------+-------------+-------------
set any other |see 4         |noError    |noError      |see 5
column to some|              |           |             |
value         |              |      see 1|          ->C|          ->D
--------------+--------------+-----------+-------------+-------------

And here's what those numbered notes mean ๐Ÿง 

  • (1) goto B or C, depending on what info the agent has ๐Ÿ’ซ
  • (2) if other variable bindings in the same PDU provide values for all the columns that are missing but required, AND all columns have acceptable values, then return noError and goto D ๐ŸŽฏ
  • (3) if other variable bindings in the same PDU provide legal values for all the columns that are missing but required, then return noError and goto C ๐ŸŽฏ
  • (4) it's up to the agent what it returns, which can be:
    • inconsistentName: because the agent doesn't choose to create that instance when the corresponding RowStatus instance doesn't exist, or
    • inconsistentValue: if the supplied value clashes with the value of some other MIB object's state, or
    • noError: because the agent chooses to create the instance.

If noError comes back, the instance of the status column also has to be created, and the new state is B or C, depending on the info the agent has. If inconsistentName or inconsistentValue comes back, the row stays in state A. ๐Ÿซ 

  • (5) depending on the MIB definition for that column or table, either noError or inconsistentValue may come back ๐Ÿคทโ€โ™€๏ธ
  • (6) the return value can be one of these errors:
    • wrongValue: because the agent doesn't support notInService (like an agent that doesn't support createAndWait), or
    • inconsistentValue: because the agent can't take the row out of service right now, maybe because it's in use and can't be de-activated.
  • (7) the return value can be this error: inconsistentValue, because the agent can't remove the row right now, maybe because it's in use and can't be de-activated ๐Ÿšซ
  • (8) the transition to D can fail. For example, if the values in the conceptual row are inconsistent, the error code would be inconsistentValue.

NOTE: other processing of this varbind (and the other varbinds of the set request) may cause a response other than noError to come back, like wrongValue, noCreation, etc. ๐Ÿ’…

Conceptual Row Creation ๐ŸŒธ

Creating a conceptual row has four potential interactions: picking an instance-identifier that isn't in use; creating the conceptual row; initializing any objects the agent doesn't supply a default for; and making the conceptual row available for use by the managed device โœจ

Interaction 1: Selecting an Instance-Identifier ๐Ÿ”

The algorithm for picking an instance-identifier is different for every conceptual row, so it's a whole vibe ๐Ÿงฉ Sometimes the instance-identifier actually means something, like the destination address of a route, and the management station picks it based on what it means.

Other times the instance-identifier just tells rows apart, so a management station that doesn't know much about the row could look at the instances that already exist and find an unused one. (This can work, but it's often super sub-optimal ๐Ÿ™ƒ And it's also kind of a questionable move for a naive management station to try creating a conceptual row at all.)

Another option: the MIB module that defines the conceptual row might provide one or more objects that help figure out an unused instance-identifier. For example, if the conceptual row is indexed by an integer-value, the module might define an object with an integer-valued SYNTAX clause just for this. That lets a management station do a management protocol retrieval operation on it ๐Ÿฆ‹ To avoid pointless collisions between competing management stations, adjacent retrievals of this object should be different ๐Ÿ’œ

Okay so picking up right where the pseudo-random index bit left off ๐Ÿ’– The management station could just pick a random number to use as the index. If that index is already taken and the agent sends back inconsistentValue to the set operation, the station should simply grab a fresh pseudo-random number and try again ๐ŸŽฒโœจ

Choosing between these index methods is all about table size ๐Ÿ“Š A MIB designer should pick based on how efficient each algorithm is for the table. If a big pile of entries is expected, it's recommended that the MIB define an object that hands back a usable index for creation. For tables with only a few entries, the pseudo-random approach is the move ๐Ÿฆ‹

Interaction 2: Creating the Conceptual Row

Once the station has an unused instance-identifier, it decides whether it wants to create and activate the conceptual row in one go, or do a negotiated back-and-forth of interactions ๐ŸŽ€

Interaction 2a: Creating and Activating the Conceptual Row

The station must first figure out the column requirements, meaning which columns it must provide values for and which it must not ๐Ÿ’… Depending on how complex the table is and how much the station knows about the agent's abilities, it can work this out locally. Otherwise, it can send a management protocol get operation to look at every column in the conceptual row it wants to create ๐Ÿ‘€ Each column can come back in one of three ways:

  • A value is returned, which means some other management station already created this conceptual row. Oops, not you! We head back to interaction 1 ๐Ÿ™ˆ
  • The exception noSuchInstance' comes back, meaning the agent implements the object-type for this column, and this column would be accessible in the MIB view used by the retrieval in at least one conceptual row if it existed. For columns with read-create access, noSuchInstance' tells the station to supply a value for that column when the row gets created ๐Ÿงš
  • The exception `noSuchObject' comes back, meaning either the agent doesn't implement the object-type for this column, or there's no conceptual row where this column would be accessible in that MIB view. So the station can't send any set operations to create an instance of this column ๐Ÿ’€

Once the column requirements are sorted, the station sends a management protocol set operation with those values ๐Ÿ”ฅ This same operation also sets the new status column instance to `createAndGo'.

When the agent processes that set operation, it checks whether it has enough info to make the conceptual row usable by the managed device ๐Ÿ” The agent gets its info from two places: the set operation that's creating the row, and implementation-specific defaults the agent supplies. Quick reminder that an agent must provide implementation-specific defaults for at least the objects it implements as read-only ๐Ÿซถ If there's enough info, the row gets created, the agent returns noError', the status column becomes active', and that's it, no more interactions needed (interactions 3 and 4 get skipped) โœจ If there isn't enough info, the row is not created and the set fails with inconsistentValue' ๐Ÿ˜ญ Then the station can send a retrieval to find out why. Did it forget a required column, or did that status column instance already exist? If it already existed, we go back to interaction 1. If it was a missing column, the station can re-send the set with the extra info, or start interaction 2 over using createAndWait' so the creation can be negotiated ๐ŸŒธ

NOTE WELL ๐Ÿ’… No matter how the station figured out the column requirements, it's possible it'll decide a column is necessary when the agent actually won't let that particular columnar instance be created or written. In that case the set operation fails with an error like noCreation' or notWritable'. The station then decides whether it really needs to set a value for that columnar instance. If not, it re-sends the set without setting a value for that instance. If it does need it, the station aborts the row creation algorithm ๐Ÿšซ

Interaction 2b: Negotiating the Creation of the Conceptual Row

The station sends a management protocol set operation that sets the desired status column instance to createAndWait' ๐Ÿค If the agent refuses to handle a request like this, the set fails with wrongValue'. (So an agent that says no to this must be ready to accept one single set operation, the interaction 2a one, with every column from its column requirements ๐Ÿ˜…) Otherwise, the conceptual row is created, the agent returns noError', and the status column is immediately set to either notInService' or notReady'. That depends on whether the agent has enough info to (attempt to) make the row usable by the managed device ๐Ÿงฉ Enough info means notInService'. Not enough means `notReady'. Either way, we move on to interaction 3 ๐Ÿฆ‹

Interaction 3: Initializing non-defaulted Objects

Now the station has to figure out the column requirements again. It sends a management protocol get operation to look at every column in the created conceptual row ๐Ÿ‘€ For each column, the response can be one of three outcomes:

  • A value is returned, meaning the agent implements the object-type for this column and had enough info to give a value. For columns with read-create access (and where the agent lets their values change after creation), getting a value back tells the station it can send more set operations, if it wants, to change that value ๐Ÿ’–
  • The exception noSuchInstance' comes back, meaning the agent implements the object-type for this column, and the column would be accessible in the MIB view used by the retrieval in at least one conceptual row if it existed. BUT the agent doesn't have enough info to provide a value, and until one is provided the row may not be made available to the managed device ๐Ÿ˜ฌ For read-create columns, noSuchInstance' tells the station it must send additional set operations to provide a value for that column ๐ŸŽ€
  • The exception `noSuchObject' comes back, meaning the agent doesn't implement the object-type for this column, or there's no conceptual row where this column would be accessible in that MIB view. So the station can't send set operations to create an instance of this column ๐Ÿ’€

If the status column value is notReady', the station must first deal with all the noSuchInstance' columns, if there are any ๐Ÿ› ๏ธ Once that's done, the status column becomes `notInService', and we move on to interaction 4 ๐ŸŒˆ

Interaction 4: Making the Conceptual Row Available

Once the station is happy with the values in the conceptual row's columns, it sends a management protocol set operation to set the status column to active' ๐Ÿš€ If the agent has enough info to make the row usable by the managed device, the set succeeds and a noError' comes back. Otherwise, the set fails with `inconsistentValue' ๐Ÿ˜ญ

NOTE WELL โš ๏ธ A conceptual row whose status column is notInService' or notReady' is unavailable to the managed device. So it's possible for the managed device to create its own instances in the gap between the set operation that sets the status column to createAndWait' and the set operation that sets it to active' ๐Ÿ‘€ In that case, when the station sets the status column to `active', the values held in the agent supersede the ones the managed device used ๐Ÿ‘‘

okay so picture this: the management station gets cut off before it can flip the status column to active (its connection dies, the network ghosts it ๐Ÿ’€), and the conceptual row just sits there in notInService or notReady, eating resources forever ๐Ÿ˜ญ. So the agent must detect conceptual rows that have been in either state for an abnormally long period of time and remove them. ๐Ÿงนโœจ The DESCRIPTION clause of the status column is supposed to say what "abnormally long" means. That period should be long enough for human response time (think time included ๐Ÿง ) between creating the row and setting it to active. If the DESCRIPTION doesn't spell it out, it's suggested that this period be approximately 5 minutes. And this cleanup isn't just for brand-new rows. It also covers previously active rows that get set to, and left in, notInService for longer than is normal for that kind of row. bestie, that's a whole glow-up for the agent ๐Ÿ’…

Conceptual Row Suspension โœจ

When a conceptual row is active, the management station may issue a management protocol set operation that sets the status column to notInService. If the agent is unwilling to do that, the set operation fails with an error of wrongValue or inconsistentValue. Otherwise the conceptual row gets taken out of service, and a noError response comes back ๐Ÿฆ‹ The DESCRIPTION clause of the status column is the one that's responsible for saying when the status column should be taken out of service (for example, so that some other column of the same conceptual row can be modified).

Conceptual Row Deletion โœจ

To delete a conceptual row, a management protocol set operation gets issued that sets the status column to destroy. This can happen regardless of the current value of the status column (so it's totally possible to delete rows that are notReady, notInService or active ๐Ÿ—‘๏ธ). If the operation succeeds, then all instances associated with the conceptual row are immediately removed. Gone, no cap ๐Ÿซถ

Here's the SYNTAX for RowStatus:

    SYNTAX       INTEGER {
                     -- the following two values are states:
                     -- these values may be read or written
                     active(1),
                     notInService(2),

                     -- the following value is a state:
                     -- this value may be read, but not written
                     notReady(3),

                     -- the following three values are
                     -- actions: these values may be written,
                     --   but are never read
                     createAndGo(4),
                     createAndWait(5),
                     destroy(6)
                 }

TimeStamp is the value of the sysUpTime object at which a specific occurrence happened ๐Ÿ•ฐ๏ธ The specific occurrence has to be defined in the description of any object that uses this type. If sysUpTime gets reset to zero because the network management (sub)system was re-initialized, then all TimeStamp values get reset too. BUT after roughly 497 days without a re-initialization, sysUpTime hits 2^^32-1 and then wraps around to zero. In that case, existing TimeStamp values do NOT change, and that can lead to some ambiguity in what a TimeStamp value means ๐Ÿ™ˆ

TimeStamp ::= TEXTUAL-CONVENTION
    STATUS       current
    SYNTAX       TimeTicks

TimeInterval is just a period of time, measured in units of 0.01 seconds โฑ๏ธ

TimeInterval ::= TEXTUAL-CONVENTION
    STATUS       current
    SYNTAX       INTEGER (0..2147483647)

DateAndTime is a date-time specification ๐Ÿ“… It's displayed using the hint "2d-1d-1d,1d:1d:1d.1d,1a1d:1d", and it's laid out like this:

DateAndTime ::= TEXTUAL-CONVENTION
    DISPLAY-HINT "2d-1d-1d,1d:1d:1d.1d,1a1d:1d"
    STATUS       current
    DESCRIPTION
            "A date-time specification.

            field  octets  contents                  range
            -----  ------  --------                  -----
              1      1-2   year*                     0..65536
              2       3    month                     1..12
              3       4    day                       1..31
              4       5    hour                      0..23
              5       6    minutes                   0..59
              6       7    seconds                   0..60
                           (use 60 for leap-second)
              7       8    deci-seconds              0..9
              8       9    direction from UTC        '+' / '-'
              9      10    hours from UTC*           0..13
             10      11    minutes from UTC          0..59

            * Notes:
            - the value of year is in network-byte order
            - daylight saving time in New Zealand is +13

            For example, Tuesday May 26, 1992 at 1:30:15 PM EDT would be
            displayed as:

                             1992-5-26,13:30:15.0,-4:0

            Note that if only local time is known, then timezone
            information (fields 8-10) is not present."
    SYNTAX       OCTET STRING (SIZE (8 | 11))

Quick breakdown of that table, bestie ๐ŸŽ€ The year is stored in network-byte order, and daylight saving time in New Zealand is +13. The example is Tuesday May 26, 1992 at 1:30:15 PM EDT, which gets displayed as:

                 1992-5-26,13:30:15.0,-4:0

And if only local time is known, the timezone fields (8-10) just aren't there ๐ŸŒธ


StorageType describes the memory realization of a conceptual row ๐Ÿ’พ A row that's volatile(2) is lost on reboot. A row that's nonVolatile(3), permanent(4) or readOnly(5) is backed up by stable storage. A permanent(4) row can be changed but not deleted, and a readOnly(5) row can't be changed OR deleted ๐Ÿ”’

If an object with this syntax has the value permanent(4) or readOnly(5), it can't be written. Flip it the other way, and if the value is other(1), volatile(2) or nonVolatile(3), it can't be modified to become permanent(4) or readOnly(5). All the illegal modifications result in a 'wrongValue' error. Also, every usage of this textual convention is required to specify the columnar objects that a permanent(4) row must, at a minimum, allow to be writable.

StorageType ::= TEXTUAL-CONVENTION
    STATUS       current
    SYNTAX       INTEGER {
                     other(1),       -- eh?
                     volatile(2),    -- e.g., in RAM
                     nonVolatile(3), -- e.g., in NVRAM
                     permanent(4),   -- e.g., partially in ROM
                     readOnly(5)     -- e.g., completely in ROM
                 }

TDomain denotes a kind of transport service ๐Ÿšš Some possible values, like snmpUDPDomain, are defined in the SNMPv2-TM MIB module, and other possible values are defined in other MIB modules. The reference for this is "The SNMPv2-TM MIB module is defined in RFC 1906."

TDomain ::= TEXTUAL-CONVENTION
    STATUS       current
    SYNTAX       OBJECT IDENTIFIER

TAddress denotes a transport service address ๐Ÿ“ A TAddress value is always interpreted within the context of a TDomain value, so every TDomain definition has to come with a textual convention for use with that TDomain. Some possible ones, like SnmpUDPAddress for snmpUDPDomain, are defined in the SNMPv2-TM MIB module, and other possible ones are defined in other MIB modules. Same reference as before: "The SNMPv2-TM MIB module is defined in RFC 1906."

TAddress ::= TEXTUAL-CONVENTION
    STATUS       current
    SYNTAX       OCTET STRING (SIZE (1..255))


END

3. Mapping of the TEXTUAL-CONVENTION macro โœจ

The TEXTUAL-CONVENTION macro is how the syntax and semantics of a textual convention get conveyed ๐Ÿงฉ Worth noting: expanding the TEXTUAL-CONVENTION macro is something that conceptually happens during implementation, NOT during run-time.

The name of a textual convention must consist of one or more letters or digits, and the initial character has to be an upper case letter. The name must not conflict with any of the reserved words listed in section 3.7 of [2]. It should not consist of all upper case letters, and it shall not exceed 64 characters in length. (Honestly though, names longer than 32 characters are not recommended ๐Ÿ™ƒ) The hyphen is not allowed in the name of a textual convention, except for information modules converted from SMIv1, which allowed hyphens in ASN.1 type assignments. And all names used for the textual conventions defined in all "standard" information modules shall be unique. No copycats allowed ๐Ÿ‘‘

3.1. Mapping of the DISPLAY-HINT clause

The DISPLAY-HINT clause doesn't need to be present. It gives a hint about how the value of an instance of an object with the syntax defined using this textual convention might be displayed ๐Ÿ‘€ The DISPLAY-HINT clause must not be present if the Textual Convention is defined with a syntax of OBJECT IDENTIFIER, IpAddress, Counter32, Counter64, or any enumerated syntax (BITS or INTEGER). Whether it makes sense for other syntax types depends on the specific definition of the Textual Convention.

When the syntax has an underlying primitive type of INTEGER, the hint is an integer-format specification with two parts ๐Ÿ”ข The first part is a single character suggesting a display format: x for hexadecimal, d for decimal, o for octal, or b for binary. For all types, leading zeros are omitted when rendering the value, and for negative values a minus sign is rendered immediately before the digits. The second part is always omitted for x, o and b, and it need not be present for d. If it IS present, the second part starts with a hyphen, followed by a decimal number that defines the implied decimal point when rendering the value. For example:

Hundredths ::= TEXTUAL-CONVENTION
    DISPLAY-HINT "d-2"
    ...
    SYNTAX     INTEGER (0..10000)

This suggests that a Hundredths value of 1234 be rendered as "12.34" ๐Ÿ’–

When the syntax has an underlying primitive type of OCTET STRING, the hint consists of one or more octet-format specifications ๐Ÿง Each specification has five parts, and each part uses (and removes) zero or more of the next octets from the value, producing the next zero or more characters to be displayed. The octets within the value are processed in order of significance, most significant first.

The five parts of an octet-format specification are:

  1. the (optional) repeat indicator. If it's present, this part is a *, and it means the current octet of the value is used as the repeat count. The repeat count is an unsigned integer (which may be zero) that specifies how many times the remainder of this octet-format specification should be successively applied. If the repeat indicator is not present, the repeat count is one. ๐Ÿ”

(2) okay so the octet length ๐Ÿงฎ is one or more decimal digits saying how many octets of the value get used and formatted by this octet-specification. Note that the octet length can be zero ๐Ÿซถ. If fewer octets than that number are left in the value, then only the lesser number of octets get used.

(3) the display format is either x for hexadecimal, d for decimal, o for octal, a for ascii, or t for UTF-8 ๐Ÿ’…. If the octet length part is greater than one and the display format part refers to a numeric format, then network-byte ordering (big-endian encoding) is used when interpreting the octets in the value. The octets processed by the t display format don't necessarily form a whole number of UTF-8 characters, and trailing octets that don't form a valid UTF-8 encoded character get discarded ๐Ÿ™ˆ.

(4) the (optional) display separator character. If it's present, this part is a single character that gets produced for display after each application of this octet-specification. However, this character is not produced for display if it would be immediately followed by the display of the repeat terminator character for this octet-specification. This character can be any character other than a decimal digit and a * โœจ.

(5) the (optional) repeat terminator character. It can only be present if the display separator character is present and this octet-specification begins with a repeat indicator. If it's present, this part is a single character that gets produced after all the zero or more repeated applications (as given by the repeat count) of this octet-specification ๐ŸŒธ. This character can be any character other than a decimal digit and a *.

Output of a display separator character or a repeat terminator character is suppressed if it would occur as the last character of the display ๐Ÿ™…โ€โ™€๏ธ.

If the octets of the value run out before all the octet-format specifications have been used, then the excess specifications get ignored. If additional octets still remain in the value after interpreting all the octet-format specifications, then the last octet-format specification gets re-interpreted to process those extra octets, over and over until no octets remain in the value ๐Ÿ”.


3.2. Mapping of the STATUS clause

The STATUS clause, which must be present, tells you whether this definition is current or historic ๐Ÿ’œ.

The value "current" means the definition is current and valid โœ….

The value "obsolete" means the definition is obsolete and should not be implemented, and it can be removed if it was implemented before. "deprecated" also means obsolete, but it still allows new or continued implementation so things stay interoperable with older, existing implementations ๐Ÿซถ.

3.3. Mapping of the DESCRIPTION clause

The DESCRIPTION clause, which must be present, holds the textual definition of the textual convention. 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 ๐Ÿ“.

3.4. Mapping of the REFERENCE clause

The REFERENCE clause, which need not be present, is a textual cross-reference to some other document ๐Ÿ”—. That could be another information module that defines a related assignment, or some other document that gives extra info relevant to this definition ๐Ÿงš.

3.5. Mapping of the SYNTAX clause

The SYNTAX clause, which must be present, defines the abstract data structure that corresponds to the textual convention ๐ŸŽ€. The data structure must be one of the alternatives defined in the ObjectSyntax CHOICE or the BITS construct (see section 7.1 in [2]). This means the SYNTAX clause of a Textual Convention can not refer to a previously defined Textual Convention, so no shortcuts there ๐Ÿ™ƒ.

An extended subset of the full capabilities of ASN.1 (1988) sub-typing is allowed, as appropriate to the underlying ASN.1 type. Any restriction on size, range or enumerations specified in this clause represents the maximal level of support that makes "protocol sense" ๐Ÿ’…. Restrictions on sub-typing are specified in detail in Section 9 and Appendix A of [2] ๐Ÿ“š.

4. Sub-typing of Textual Conventions ๐Ÿงฉ

The SYNTAX clause of a TEXTUAL CONVENTION macro may be sub-typed in the same way as the SYNTAX clause of an OBJECT-TYPE macro (see section 11 of [2]) ๐Ÿ’–.

5. Revising a Textual Convention Definition ๐Ÿฆ‹

It may be desirable to revise the definition of a textual convention after experience has been gained with it ๐Ÿ‘€. Still, changes are not allowed if they have any potential to cause interoperability problems "over the wire" between an implementation using an original specification and an implementation using an updated specification. Those changes can only be accommodated by defining a new textual convention, which means a new name ๐Ÿšซ.

The following revisions are allowed:

(1) A SYNTAX clause containing an enumerated INTEGER may have new enumerations added or existing labels changed. Similarly, named bits may be added or existing labels changed for the BITS construct ๐ŸŒˆ.

(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". When making such a change, the DESCRIPTION clause should be updated to explain the rationale ๐Ÿ“ฃ.

(3) A REFERENCE clause may be added or updated ๐Ÿ”—.

(4) A DISPLAY-HINTS clause may be added or updated ๐Ÿ“.

(5) Clarifications and additional information may be included in the DESCRIPTION clause ๐ŸŒท.

(6) Any editorial change ๐Ÿงธ.

Note that with the introduction of the TEXTUAL-CONVENTION macro, there is no longer any need to define types in the following manner:

     DisplayString ::= OCTET STRING (SIZE (0..255))

When revising an information module containing a definition like this, that definition should be replaced by a TEXTUAL-CONVENTION macro ๐Ÿช„.

6. Security Considerations ๐Ÿ”

This document defines the means to define new data types for the language used to write and read descriptions of management information. These data types have no security impact on the Internet ๐Ÿ›ก๏ธ. Not a scary section at all, bestie ๐Ÿฅฐ.

7. Editors' Addresses ๐Ÿ’Œ

Keith McCloghrie
Cisco Systems, Inc.
170 West Tasman Drive
San Jose, CA  95134-1706
USA
Phone: +1 408 526 5260
EMail: kzm@cisco.com

David Perkins
SNMPinfo
3763 Benton Street
Santa Clara, CA 95051
USA
Phone: +1 408 221-8702
EMail: dperkins@snmpinfo.com

Juergen Schoenwaelder
TU Braunschweig
Bueltenweg 74/75
38106 Braunschweig
Germany
Phone: +49 531 391-3283
EMail: schoenw@ibr.cs.tu-bs.de

8. References ๐Ÿ“–

[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] McCloghrie, K., Perkins, D., Schoenwaelder, J., Case, J., Rose, M. and S. Waldbusser, "Structure of Management Information Version 2 (SMIv2)", STD 58, RFC 2578, April 1999.

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

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

Bestie, this part is the legal stuff, so I'm keeping every term exactly as it is ๐Ÿงพ. This document and translations of it may be copied and furnished to others. Derivative works that comment on or otherwise explain it, or help with its implementation, may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind. That's provided the above copyright notice and this paragraph are included on all such copies and derivative works ๐Ÿ’œ. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations. The exceptions are when it's needed for developing Internet standards, in which case the procedures for copyrights defined in the Internet Standards process must be followed, or when it's required to translate it into languages other than English ๐ŸŒ.

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns โ™พ๏ธ.

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. ๐Ÿ’€
๐Ÿ“ฆ where this page comes from