RFC 2561

Base Definitions of Managed Objects for TN3270E Using SMIv2

πŸ“… published April 1999, from ietf

RFC 2561 πŸ“œ Base Definitions of Managed Objects for TN3270E Using SMIv2 πŸŽ€

okay bestie, RFC 2561 is giving standards track πŸ‘‘. It was written by K. White and R. Moore, both at IBM Corp., and it's dated April 1999 πŸ“…. The header has no Obsoletes or Updates line, so this one doesn't replace or patch any older RFC. It's a fresh starter pack 🌸.

Status of This Memo ✨

This document is an Internet standards track protocol for the Internet community πŸ¦‹. It's literally asking for discussion and suggestions for improvements πŸ₯Ί. If you want the official tea on where this protocol stands, check the current "Internet Official Protocol Standards" (STD 1) πŸ’…. Distribution of this memo is unlimited, so share the vibes 🌈.

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

Abstract 🌸

This memo defines a Management Information Base (MIB) for configuring and managing TN3270E servers πŸ–₯️. TN3270E, defined by RFC 2355 [19], is the glow-up on Telnet 3270 (TN3270) terminal emulation practices ✨. If you want a sample of what TN3270 practices look like, check out RFC 1041 [18], STD 8, RFC 854 [16], and STD 31, RFC 860 [17] πŸ“š.

The MIB in this memo gives generic support for both host and gateway TN3270E server implementations 🧚. A TN3270E server connects a Telnet client doing 3270 emulation to a target SNA host. It does this over two networks: a client-side network (client to TN3270E server) and an SNA Network (TN3270E server to target SNA host) πŸ”₯. The client-side network is typically TCP/IP, but it doesn't have to be πŸ’–.

A host TN3270E server is an implementation where the TN3270E server is collocated with the Systems Network Architecture (SNA) System Services Control Point (SSCP) for the dependent Secondary Logical Units (SLUs) it makes available to clients connecting into an SNA network πŸ‘‘. A gateway TN3270E server lives on an SNA node other than an SSCP. That could be an SNA type 2.0 node, a boundary-function-attached type 2.1 node, or an APPN node playing the role of a Dependent LU Requester (DLUR) πŸ¦‹. Host and gateway implementations usually differ a lot in their internal implementation and system definition (SYSDEF) methods πŸ™ˆ.

The MIB is meant to be extended by subsequent memos 🌈. For example, one extension lets you collect TN3270E response time data ⏱️.

Table of Contents πŸ“š

   1.0  Introduction  . . . . . . . . . . . . . . . . . . . . . . .   2
   2.0  The SNMP Network Management Framework   . . . . . . . . . .   3
   3.0  Structure of the MIB  . . . . . . . . . . . . . . . . . . .   4
   3.1  TN3270E Server Control  . . . . . . . . . . . . . . . . . .   5
     3.1.1  tn3270eSrvrConfTable  . . . . . . . . . . . . . . . . .   5
     3.1.2  tn3270eSrvrPortTable  . . . . . . . . . . . . . . . . .   6
     3.1.3  tn3270eSrvrStatsTable   . . . . . . . . . . . . . . . .   7
   3.2  TN3270E Server Resource Configuration   . . . . . . . . . .   7
   3.3  Resource Name / Client Address Mappings   . . . . . . . . .   8
     3.3.1  tn3270eSnaMapTable  . . . . . . . . . . . . . . . . . .   8
     3.3.2  tn3270eResMapTable  . . . . . . . . . . . . . . . . . .   9
     3.3.3  tn3270eTcpConnTable   . . . . . . . . . . . . . . . . .   9
   3.4  Advisory Spin Lock Usage  . . . . . . . . . . . . . . . . .   9
   3.5  Row Persistence   . . . . . . . . . . . . . . . . . . . . .  10
   3.6  IANA Considerations   . . . . . . . . . . . . . . . . . . .  10
   4.0  Definitions   . . . . . . . . . . . . . . . . . . . . . . .  11
   5.0  Security Considerations   . . . . . . . . . . . . . . . . .  51
   6.0  Intellectual Property   . . . . . . . . . . . . . . . . . .  52
   7.0  Acknowledgments   . . . . . . . . . . . . . . . . . . . . .  53
   8.0  References  . . . . . . . . . . . . . . . . . . . . . . . .  53
   9.0  Authors' Addresses  . . . . . . . . . . . . . . . . . . . .  55
   Full Copyright Statement   . . . . . . . . . . . . . . . . . . .  56

1.0 Introduction πŸŽ€

This document is a product of the TN3270E Working Group 🫢. Its purpose is to define a MIB module that a TCP/IP implementation can support for configuring and managing TN3270E servers 🌸.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119, reference [22] πŸ’….

2.0 The SNMP Network Management Framework πŸ¦‹

okay so the SNMP Management Framework is made up of five major components 🧩:

  • An overall architecture, described in RFC 2271 [1].
  • Mechanisms for describing and naming objects and events for the purpose of management. The first version of this Structure of Management Information (SMI) is called SMIv1 and is described in STD 16, RFC 1155 [2], STD 16, RFC 1212 [3] and RFC 1215 [4]. The second version, called SMIv2, is described in RFC 1902 [5], RFC 1903 [6] and RFC 1904 [7].
  • Message protocols for transferring management information. The first version of the SNMP message protocol is called SNMPv1 and is described in STD 15, RFC 1157 [8]. A second version, SNMPv2c, which is not an Internet standards track protocol, is described in RFC 1901 [9] and RFC 1906 [10]. The third version of the message protocol is called SNMPv3 and is described in RFC 1906 [10], RFC 2272 [11] and RFC 2274 [12].
  • Protocol operations for accessing management information. The first set of protocol operations and associated PDU formats is described in STD 15, RFC 1157 [8]. A second set of protocol operations and associated PDU formats is described in RFC 1905 [13].
  • A set of fundamental applications described in RFC 2273 [14], plus the view-based access control mechanism described in RFC 2275 [15].

Managed objects are accessed through a virtual information store called the Management Information Base, or MIB πŸ—‚οΈ. Objects in the MIB are defined using the mechanisms defined in the SMI πŸ”₯.

This memo specifies a MIB module that is compliant to SMIv2 ✨. A MIB conforming to SMIv1 can be produced through the appropriate translations. The resulting translated MIB needs to be semantically equivalent, except where objects or events are left out because no translation is possible (use of Counter64) πŸ™ˆ. Some machine readable information in SMIv2 gets turned into textual descriptions in SMIv1 during translation. Still, this loss of machine readable information is not considered to change the semantics of the MIB πŸ’–.

3.0 Structure of the MIB 🧩

The TN3270E-MIB is split into the following components πŸ“:

  • TN3270E Server Control
  • TN3270E Server Resource Configuration
  • Resource/Client Address Mappings

There are three additional sections to address πŸ’œ:

  • Advisory Spin Lock Usage
  • Row Persistence
  • IANA Considerations

The TN3270E-MIB is defined primarily for TN3270E servers 🎯. This memo doesn't explicitly address use of the MIB by TN3270 servers that don't support the TN3270E protocol. A significant number of the objects in the MIB do apply to the TN3270-only case, but that case wasn't addressed, since a TN3270-only server is unlikely to implement this MIB πŸ™ƒ.

The SYSAPPL-MIB, reference [24], contains the Utf8String textual convention (TC) that the TN3270E-MIB imports πŸ“–. This TC is used for some MIB objects that hold textual information, and it enables internationalization of text strings. The DisplayString TC does not 🌍. The SNMP-FRAMEWORK-MIB, reference [1], contains the SnmpAdminString TC that the TN3270E-MIB also imports. Like Utf8String, this TC enables internationalization of text strings. On top of that, it gives some guidelines on the length and content of the strings πŸ’….

Implementing the SYSAPPL-MIB is not actually a prerequisite for implementing the TN3270E-MIB πŸ™Œ. On the other hand, implementing the TN3270E-MIB doesn't rule out implementing the SYSAPPL-MIB as well.

When both MIBs are implemented, the primary index into most of the TN3270E-MIB tables, tn3270eSrvrConfIndex, SHOULD equal one of the SYSAPPL-MIB's sysApplElmtRunIndex values 🧚. In this case, the entry in the sysApplElmtRunTable gives extra info on a TN3270E server ✨.

The MIB in this memo supports both IPv4 and IPv6 addressing 🌐. Two textual conventions, IANATn3270eAddrType and Tn3270eAddress, are defined for this purpose. IANATn3270eAddress is basically equivalent to the TAddress TC, defined by RFC 1903 πŸ¦‹. The difference is that IANATn3270eAddress allows a zero-length octet string, while TAddress doesn't. It's important that IANATn3270eAddress allow for the absence of an address, because some objects with this syntax are used as table indexes and have special meanings when they contain zero-length strings 🫢.

The IANATn3270eAddrType textual convention is used instead of the TDomain TC (defined by RFC 1903) for identifying the contents of a tn3270eTAddress object πŸŽ€. TDomain uses an OID to characterize the contents of an associated TAddress object. IANATn3270eAddrType was chosen over TDomain because, with a SYNTAX of Unsigned32 (enumeration type), it's way simpler to use as a component in an instance identifier 🧠. It was placed in the IANA-administered module so values can be added later to cover cases not handled by the TN3270E-MIB itself, like proxy servers 🌈.

3.1 TN3270E Server Control πŸŽ›οΈ

This group of objects provides for TN3270E server configuration and control πŸ’–. It consists of three tables:

  • tn3270eSrvrConfTable
  • tn3270eSrvrPortTable
  • tn3270eSrvrStatsTable

The tn3270eSrvrConfTable is the primary table in the entire TN3270E-MIB πŸ‘‘. As section 3.1.1 indicates, each TN3270E server is represented by an entry in this table, indexed by tn3270eSrvrConfIndex. Most of the other tables defined by the TN3270E-MIB use tn3270eSrvrConfIndex as their primary index πŸ”₯. Entries in these tables MUST NOT exist for a TN3270E server when it doesn't have a tn3270eSrvrConfigEntry πŸ™…β€β™€οΈ.

3.1.1 tn3270eSrvrConfTable ✨

okay so the tn3270eSrvrConfTable is basically HQ for setting up and managing TN3270E servers πŸ’…. Like most of the other tables in the TN3270E-MIB, it's indexed by an unsigned integer called tn3270eSrvrConfIndex πŸ¦‹. That primary index is what lets one SNMP agent handle multiple TN3270E servers, which is so iconic πŸ‘‘. Across everything one SNMP agent returns, tn3270eSrvrConfIndex values MUST be unique πŸ”₯, but they don't need to be contiguous.

The tn3270eSrvrConfInactivityTimer object sets the inactivity period for user traffic on TN3270 and TN3270E sessions ⏰.

These four objects are a team 🧚. Together they set the parameters for the "Telnet Timing Mark Option" from RFC 860 [17]:

  • tn3270eSrvrConfConnectivityChk
  • tn3270eSrvrConfTmNopInterval
  • tn3270eSrvrConfTmNopInactTime
  • tn3270eSrvrConfTmTimeout

tn3270eSrvrConfConnectivityChk lets a Management Station choose between a NOP command or a TIMING-MARK command. A NOP is lighter on overhead than a TIMING-MARK, since the client doesn't send a reply 🫢.

tn3270eSrvrConfAdminStatus and tn3270eSrvrConfOperStatus are the remote start and stop buttons for a TN3270E server, and they also show its current state πŸŽ€. tn3270eSrvrConfFunctionsSupported tells you which TN3270 and TN3270E options a server supports πŸ’œ. tn3270eSrvrConfSessionTermState is a server-wide option that defines what SHOULD occur when the SNA portion of a TN3270 or TN3270E session terminates, with respect to the associated TCP connection 😭.

tn3270eSrvrConfSrvrType says whether the server is a host or a gateway server πŸ“. tn3270eSrvrConfContact is a scratch pad where a server administrator can store info for later πŸ“. tn3270eSrvrConfLastActTime reports the DateAndTime when the server was most recently activated ⭐. The special value of all '00'Hs means the server has never been active πŸ™ˆ.

tn3270eSrvrConfRowStatus is what gives you row creation and deletion on this table 🌈.

3.1.2 tn3270eSrvrPortTable

The tn3270eSrvrPortTable represents the local TCP ports tied to a TN3270E server. This matters because some TN3270E server implementations support multiple local ports πŸšͺ. A tn3270eSrvrPortEntry is indexed by:

  • tn3270eSrvrConfIndex
  • tn3270eSrvrConfPort
  • tn3270eSrvrConfPortAddrType
  • tn3270eSrvrConfPortAddress

Some implementations restrict a local TCP port to one particular local IP address, instead of letting connections from any local IP address come in through that port πŸ”’. tn3270eSrvrConfPortAddrType and tn3270eSrvrConfPortAddress let that restriction be represented in the MIB πŸ’–. A TN3270E server that doesn't restrict connections over a port to a local IP Address SHALL use the value unknown(0) for tn3270eSrvrConfPortAddrType, and a zero-length octet string for tn3270eSrvrConfPortAddress 🫢.

3.1.3 tn3270eSrvrStatsTable

The tn3270eSrvrStatsTable is a whole collection of objects giving general usage stats for a TN3270E server πŸ“Š. An entry can cover the total activity for a server, or the activity on a port, or the activity on a port-and-local-address basis.

An implementation of this table MUST use only one of the three levels of refinement that the indexing supports, for the entries tied to a single TN3270E server πŸ™….

The objects reporting maximum, in-use, and spare LUs for terminals and printers assume that terminal resources and printer resources come from disjoint, dedicated pools πŸ–¨οΈ. An implementation where both LU types come from a single shared pool should return the following values:

  • maximum: maximum size of the shared pool
  • in-use: number currently in use as this type of LU
  • spare: maximum - (terminal in-use + printer in-use)

3.2 TN3270E Server Resource Configuration

The following three tables handle configuring resources at a TN3270E server πŸ—‚οΈ:

  • tn3270eClientGroupTable
  • tn3270eResPoolTable
  • tn3270eClientResMapTable

tn3270eClientGroupTable and tn3270eResPoolTable let implementations define groupings of both client addresses and resource pools, so client addresses can be mapped to resources 🧩. tn3270eClientResMapTable is the one that maps a client group to a resource pool πŸ—ΊοΈ.

3.3 Resource Name / Client Address Mappings

The TN3270E-MIB has three tables for mapping resource names to client addresses, and client addresses to resource names πŸ”:

  • tn3270eSnaMapTable
  • tn3270eResMapTable
  • tn3270eTcpConnTable

3.3.1 tn3270eSnaMapTable

The tn3270eSnaMapTable is a read-only table that maps a secondary LU's SNA network name to the name it goes by locally at the TN3270E server πŸ‘€. For correlation with data from the SNA network, the name of the associated primary LU also shows up in a tn3270eSnaMapEntry. An entry gets created when the Activate LU (ACTLU) request carrying the SLU's SNA network name arrives from the SSCP, and it gets deleted when the SLU is deactivated 🌸.

So here's how it works 🧚. A TN3270E server gives a client access to an SNA application by linking a TCP connection from that client to an SNA secondary LU (SLU) at the server. That SLU then has an SNA session with a primary LU (PLU) on an SNA host, and the PLU represents the application the client is talking to. The TN3270E-MIB includes two tables for mapping back and forth between the SNA name of the PLU, the SNA name of the SLU, and the TCP connection with the client πŸ”—.

To get these name mappings, you have to understand one subtle thing πŸ€“. The names of the SLUs at the TN3270E server are often different from the names the SLUs go by everywhere else in the SNA network. The TN3270E-MIB calls these two kinds of SLU names "local names" and "SSCP-supplied names". The second term means the name the SLU has in the SNA network comes to the TN3270E server from the SNA System Services Control Point ✨.

SSCPs don't always send SLU names down to secondary LUs. Sometimes that capability has to be turned on πŸ”›. For SLUs served by a Dependent LU Requester (DLUR), the SSCP always sends SLU names to the DLUR. The DLUR's PU/LU Network Name Forwarding function does need to be enabled, though, so it passes along the SLU names it gets from the SSCP down to the PUs it serves πŸ“¨.

For SLUs associated with an SNA type 2.0 node (or with a boundary-function-attached type 2.1 node) that aren't served by a DLUR, including SLU names on ACTLU has to be enabled explicitly at the SSCP through local configuration βš™οΈ.

3.3.2 tn3270eResMapTable

The tn3270eResMapTable is a read-only table that maps a resource name to a client's address πŸ“. An entry gets created when a TCP connection is received by a TN3270E server and mapped to a resource. The entry gets deleted when that resource-to-address association is no longer valid πŸ—‘οΈ.

3.3.3 tn3270eTcpConnTable

The TCP Connection Table is currently defined by RFC 2012 (Refer to reference [20], TCP-MIB Definitions) πŸ“š. It has these objects:

  • tcpConnState (INTEGER)
  • tcpConnLocalAddress (IpAddress)
  • tcpConnLocalPort (INTEGER)
  • tcpConnRemAddress (IpAddress)
  • tcpConnRemPort (INTEGER)

It's indexed by: tcpConnLocalAddress, tcpConnLocalPort, tcpConnRemAddress, and tcpConnRemPort.

The tn3270eTcpConnTable is where the current set of TN3270 and TN3270E sessions at a TN3270E server gets kept track of πŸ“‹. Its relationship with the tcpConnTable isn't one-to-one, because the tn3270eTcpConnTable only holds info about TN3270(E) sessions 🀏.

The two tables index differently too πŸ™ƒ. Instead of IpAddress objects, the tn3270eTcpConnTable uses Tn3270eAddress and IANATn3270eAddrType object pairs to specify client addresses (both local and remote). This is what makes IPv6 addresses supported 🌐. The remote address pair also comes before the local address pair in the index clause, so a GET-NEXT operation can use just the remote address pair πŸƒ.

3.4 Advisory Spin Lock Usage

Within the TN3270E-MIB, tn3270eConfSpinLock is defined as an advisory lock πŸ”. It lets cooperating TN3270E-MIB applications coordinate their use of the tn3270eSrvrConfTable, the tn3270eSrvrPortTable, the tn3270eClientGroupTable, the tn3270eResPoolTable, and the tn3270eClientResMapTable. When an application creates a new entry or changes an existing one in any of these tables, it SHOULD make use of tn3270eConfSpinLock to serialize its changes or additions 🫢. Since this is an advisory lock, agents SHALL NOT enforce its use by management applications. Agents MUST, however, implement the tn3270eConfSpinLock object πŸ’ͺ.

3.5 Row Persistence

These tables allow remote creation of their entries by including RowStatus objects 🎈:

  • tn3270eSrvrConfTable
  • tn3270eSrvrPortTable
  • tn3270eClientGroupTable
  • tn3270eResPoolTable
  • tn3270eClientResMapTable

An implementation SHOULD NOT retain SNMP-created entries in these tables across reIPLs (Initial Program Loads) of the corresponding TN3270E server πŸ”„. The reason is that management applications need to see consistent behavior when it comes to the persistence of the table entries they create.

The expectation is that local, implementation-dependent configuration info will be used to define the initial and persistent configurations for TN3270E server usage πŸ› οΈ. So there's no need to turn on persistence of table entries by adding StorageType (refer to RFC 1903 [6]) objects to these tables.

3.6 IANA Considerations

The tn3270eSrvrFunctionsSupported, tn3270eTcpConnFunctions, tn3270eTcpConnClientIdFormat, and tn3270eTcpConnLogInfo objects, along with a bunch of objects that identify various address types, resource types, and device types, use textual conventions imported from the IANATn3270eTC-MIB 🏷️. Defining these textual conventions in their own MIB module means new values can be added without issuing a new version of this document πŸŽ‰. The Internet Assigned Numbers Authority (IANA) is responsible for assigning all Internet numbers, including various SNMP-related numbers, and it will administer the values tied to these textual conventions πŸ‘‘.

The rules for additions or changes to the IANATn3270eTC-MIB are laid out in the DESCRIPTION clause attached to its MODULE-IDENTITY statement πŸ“œ.

The current version of the IANATn3270eTC-MIB can be accessed from the IANA home page at: "http://www.iana.org/" 🌍.

4.0 Definitions ✨

  TN3270E-MIB DEFINITIONS ::= BEGIN

Okay bestie, the IMPORTS list is literally a whole guest list πŸ’… Every name here gets pulled in from another module, so the MIB can use them without redefining anything. Let's keep going πŸŽ€

  IMPORTS
      MODULE-IDENTITY, OBJECT-TYPE, Unsigned32, TimeTicks,
      IpAddress, Counter32, Gauge32, Counter64
          FROM SNMPv2-SMI
      TEXTUAL-CONVENTION, RowStatus, TestAndIncr, DateAndTime,
      TimeStamp
          FROM SNMPv2-TC
      MODULE-COMPLIANCE, OBJECT-GROUP
          FROM SNMPv2-CONF
      snanauMIB
          FROM SNA-NAU-MIB
      Utf8String
          FROM SYSAPPL-MIB
      SnmpAdminString
          FROM SNMP-FRAMEWORK-MIB
      IANATn3270eAddrType, IANATn3270eAddress,
      IANATn3270eClientType, IANATn3270Functions,
      IANATn3270ResourceType, IANATn3270DeviceType,
      IANATn3270eLogData
          FROM IANATn3270eTC-MIB;

    tn3270eMIB MODULE-IDENTITY
        LAST-UPDATED "9807270000Z" -- July 27, 1998
        ORGANIZATION "TN3270E Working Group"
        CONTACT-INFO
            "Kenneth White (kennethw@vnet.ibm.com)
             IBM Corp. - Dept. BRQA/Bldg. 501/G114
             P.O. Box 12195
             3039 Cornwallis
             RTP, NC 27709-2195
             USA

             Robert Moore (remoore@us.ibm.com)
             IBM Corp. - Dept. BRQA/Bldg. 501/G114
             P.O. Box 12195
             3039 Cornwallis
             RTP, NC 27709-2195
             USA
             +1-919-254-4436"
        DESCRIPTION
            "This module defines a portion of the management
            information base (MIB) for managing TN3270E servers."
        REVISION  "9807270000Z" -- July 27, 1998
        DESCRIPTION
            "RFC nnnn (Proposed Standard)" -- RFC Editor to fill in
        ::= { snanauMIB 8 }

The contact info is the crew who wrote it, so if you're confused, they're the ones to slide into the DMs 🫢

Okay now the textual conventions, which are basically custom types with a whole vibe check πŸ”₯

  -- Textual Conventions

  SnaResourceName ::= TEXTUAL-CONVENTION
      STATUS      current
      DESCRIPTION
          "The textual convention for defining an SNA resource
           name. A fully qualified SNA resource name, consisting
           of a 1 to 8 character network identifier (NetId), a
           period ('.'), and a 1 to 8 character resource name
           (ResName).

           The NetId and ResName are constructed from the
           uppercase letters 'A' - 'Z' and the numerics '0' - '9',
           all encoded in ASCII, with the restriction that the
           first character of each must be a letter.  Blanks are
           not allowed.

           Earlier versions of SNA permitted three additional
           characters in NetIds and ResNames:  '#', '@', and '$'.
           While this use of these characters has been retired,
           a Management Station should still accept them for
           backward compatibility.

           Note: This Textual Convention is not subject to
           internationalization, and does not use the character
           encodings used by the Utf8String Textual Convention."
      SYNTAX     OCTET STRING (SIZE(0..17))

  Tn3270eTraceData ::= TEXTUAL-CONVENTION
      STATUS      current
      DESCRIPTION
          "An octet string representing trace data from the
          Telnet half of a TN3270E session, from the SNA half,
          or from both.  The octet string contains a sequence
          of trace elements, with the trace elements in the
          string ordered from earliest to latest.

          Each trace element has the following form:

                  +---+---+----+----------------------+
                  !length !type!data                  !
                  +---+---+----+----------------------+

            where:

            length = two-octet length of the data portion of the
                     trace element, not including the length and
                     type octets

            type   = one-octet code point characterizing the data;
                     defined values are:

                     X'01' telnet PDU from the server to the client
                     X'02' telnet PDU from the client to the server
                     X'03' SNA data from the server to the SNA host
                     X'04' SNA data from the SNA host to the server

            data   = initial part of a PDU.

          It is implementation-dependent where the 'initial part of
          a PDU' starts.  For SNA data, however, the starting point
          SHOULD be the first byte of the TH.  For IP data the
          starting point SHOULD be the first byte of the IP header.

          It is left to implementations to determine how much of
          each PDU to return in a trace element.

          The zero-length string indicates that no trace
          data is available."
      SYNTAX OCTET STRING (SIZE (0 | 3..4096))

Okay the trace data one is giving diagram energy πŸ¦‹ The little box picture is literally a packet with a length, a type, and then the data, and it's all in the code block so nothing gets scrambled ✨

Top-level structure time 🌸 These are just the three big buckets the MIB lives in: notifications, objects, and conformance.

  -- Top-level structure of the MIB

  tn3270eNotifications  OBJECT IDENTIFIER ::= { tn3270eMIB 0 }
  tn3270eObjects        OBJECT IDENTIFIER ::= { tn3270eMIB 1 }
  tn3270eConformance    OBJECT IDENTIFIER ::= { tn3270eMIB 3 }

  -- MIB Objects

  tn3270eSrvrConfTable OBJECT-TYPE
      SYNTAX      SEQUENCE OF Tn3270eSrvrConfEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "This table defines the configuration elements for
          TN3270E servers.  The number of entries in this table
          is expected to vary depending on the location of the
          table.  A particular TN3270E server is expected to
          have a single entry.  Modeling of the configuration
          elements as a table allows multiple TN3270E
          servers to be serviced by the same SNMP agent.

          An implementation SHOULD NOT retain an SNMP-created
          entry in this table across re-IPLs (Initial Program
          Loads) of the corresponding TN3270E server."

      ::= { tn3270eObjects 1 }

  tn3270eSrvrConfEntry OBJECT-TYPE
      SYNTAX      Tn3270eSrvrConfEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "Definition of the configuration elements for a single
          TN3270E server."
      INDEX       { tn3270eSrvrConfIndex }
      ::= { tn3270eSrvrConfTable 1 }

  Tn3270eSrvrConfEntry ::= SEQUENCE {
      tn3270eSrvrConfIndex             Unsigned32,
      tn3270eSrvrConfInactivityTimeout Unsigned32,
      tn3270eSrvrConfConnectivityChk   INTEGER,
      tn3270eSrvrConfTmNopInactTime    Unsigned32,
      tn3270eSrvrConfTmNopInterval     Unsigned32,
      tn3270eSrvrFunctionsSupported    IANATn3270Functions,
      tn3270eSrvrConfAdminStatus       INTEGER,
      tn3270eSrvrConfOperStatus        INTEGER,
      tn3270eSrvrConfSessionTermState  INTEGER,
      tn3270eSrvrConfSrvrType          INTEGER,
      tn3270eSrvrConfContact           SnmpAdminString,
      tn3270eSrvrConfRowStatus         RowStatus,
      tn3270eSrvrConfLastActTime       DateAndTime,
      tn3270eSrvrConfTmTimeout         Unsigned32
    }

  tn3270eSrvrConfIndex  OBJECT-TYPE
      SYNTAX      Unsigned32 (1..4294967295)
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
         "Identifier for a single TN3270E server.

         tn3270eSrvrConfIndex values need not be
         contiguous."
      ::= { tn3270eSrvrConfEntry 1 }

  tn3270eSrvrConfInactivityTimeout OBJECT-TYPE
      SYNTAX      Unsigned32 (0..99999999)
      UNITS "seconds"
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION
         "The inactivity time-out specified in seconds.  When a
          connection has been inactive for the number of seconds
          specified by this object it is closed.  Only user traffic
          is considered when determining whether there has been
          activity on a connection.

          The default value 0 means that no inactivity time-out is
          in effect."
      DEFVAL { 0 }
      ::= { tn3270eSrvrConfEntry 2 }

  tn3270eSrvrConfConnectivityChk OBJECT-TYPE
      SYNTAX      INTEGER {
                            timingMark(1),
                            nop(2),
                            noCheck(3)
                          }
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION
         "This object enables TIMING-MARK processing, NOP
          processing, or neither for a TN3270E server."
      DEFVAL { noCheck }
      ::= { tn3270eSrvrConfEntry 3 }

  tn3270eSrvrConfTmNopInactTime OBJECT-TYPE
      SYNTAX      Unsigned32 (1..86400) -- 1 second to 24 hours
      UNITS "seconds"
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION
         "The amount of time a connection must have had no
         traffic on it in order for a TIMING-MARK or NOP request
         to be sent on the connection.  This value applies only
         when connections are being examined for recent activity
         on a scan interval controlled by the value of the
         tn3270eSrvrConfTmNopInterval object."
      DEFVAL { 600 }   -- 10 minutes
      ::= { tn3270eSrvrConfEntry 4 }

  tn3270eSrvrConfTmNopInterval OBJECT-TYPE
      SYNTAX      Unsigned32 (1..86400) -- 1 second to 24 hours
      UNITS "seconds"
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION

         "The scan interval to be used by a TN3270E server when
         it examines its Telnet connections for recent activity.
         The server scans its Telnet connections on the interval
         provided by this object, looking for ones that have been
         idle for more than the value provided by the
         tn3270eSrvrConfTmNopInactTime object.  A TIMING-MARK or
         NOP request is sent for each connection that has
         exhibited no activity for this period of time."
      DEFVAL { 120 }   -- 2 minutes
      ::= { tn3270eSrvrConfEntry 5 }

  tn3270eSrvrFunctionsSupported OBJECT-TYPE
      SYNTAX    IANATn3270Functions
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
         "This object indicates the functions supported by a
          TN3270E server."
      DEFVAL { { scsCtlCodes, dataStreamCtl,
                 responses, bindImage, sysreq } }
      ::= { tn3270eSrvrConfEntry 6 }

  tn3270eSrvrConfAdminStatus OBJECT-TYPE
      SYNTAX  INTEGER {
                        up(1),
                        down(2),
                        stopImmediate(3)
                      }
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION
          "The desired state of the TN3270E server represented
           by this entry in the table:

           up(1)            - Activate this TN3270E server.
           down(2)          - Informs the associated TN3270E
                              server to gracefully terminate
                              its processing.
           stopImmediate(3) - Informs the associated TN3270E
                              server to terminate itself
                              immediately.

           When a managed system creates an entry in this table,
           tn3270eSrvrConfAdminStatus and tn3270eSrvrConfOperStatus
           are initialized as up(1) by default.

           The exact behavior of a server in response to a down(2)
           or stopImmediate(3) command is left implementation-
           dependent.  A TN3270E server that is capable of it
           SHOULD close all of its TN3270 and TN3270E sessions
           during a graceful termination.

           Often the function enabled via stopImmediate(3) is used
           as a last resort by a system administrator, to attempt
           to either bring down a hung TN3270E server or free up
           its resources immediately to aid in general system
           availability, or to shut down a TN3270E server that is
           not recognizing a down(2) request.

           A TN3270E server that does not distinguish between
           down(2) or stopImmediate(3) transitions should not
           support stopImmediate(3)."
      DEFVAL { up }
      ::= { tn3270eSrvrConfEntry 7 }

And that's the vibe for this part! πŸ“ The table definitions are the heart of it, and everything here is copied exactly so nothing gets lost in translation 🧚

okay bestie, the rest of the conf table is where the server's personality really comes out πŸ’…βœ¨

  tn3270eSrvrConfOperStatus OBJECT-TYPE
      SYNTAX  INTEGER {
                       up(1),
                       down(2),
                       busy(3),
                       shuttingDown(4)
                      }
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
         "The current operational state of a TN3270E server.
         The following values are defined:

          up(1)            - the server is active and accepting
                             new client connections
          down(2)          - the server is not active
          busy(3)          - the server is active, but is not
                             accepting new client connections
                             because it lacks the resources to
                             do so
          shuttingDown(4)  - the server is active, but is not
                             accepting new client connections
                             because it is in the process of
                             performing a graceful shutdown."
      DEFVAL { up }
      ::= { tn3270eSrvrConfEntry 8 }

  tn3270eSrvrConfSessionTermState OBJECT-TYPE
      SYNTAX  INTEGER {
                        terminate(1),
                        luSessionPend(2),
                        queueSession(3)
                      }
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION
         "This object determines what a TN3270E server
          should do when a TN3270 Session terminates:
         terminate(1)     => Terminate the TCP connection.
         luSessionPend(2) => Do not drop the TCP connection
                             associated with a client when its
                             TN3270 session ends.  Processing
                             should redrive session initialization
                             as if the client were first connecting.
         queueSession(3)  => This value relates to the Close
                             Destination PASS (CLSDST PASS) operation
                             in VTAM.  An example provides the
                             easiest explanation.  Suppose a TN3270E
                             client is in session with APPL1, and
                             APPL1 does a CLSDST PASS of the client's
                             session to APPL2.  queueSession(3)
                             specifies that the TN3270E server must
                             keep the TCP connection with the client
                             active after it receives the UNBIND from
                             APPL1, waiting for the BIND from APPL2."
      DEFVAL { terminate }
      ::= { tn3270eSrvrConfEntry 9 }

  tn3270eSrvrConfSrvrType OBJECT-TYPE
      SYNTAX      INTEGER {
                            host(1),
                            gateway(2)
                          }
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object indicates the type of TN3270E server.
          The existence of MIB tables and objects that will be
          defined by follow-on MIBs may be predicated on whether
          the TN3270E server can be local to the same host as a
          target application (host(1)) or will always be remote
          (gateway(2)).

          A host TN3270E server refers to an implementation where
          the TN3270E server is collocated with the Systems
          Network Architecture (SNA) System Services Control Point
          (SSCP) for the dependent Secondary Logical Units (SLUs)
          that the server makes available to its clients for
          connecting into an SNA network.

          A gateway TN3270E server resides on an SNA node other
          than an SSCP, either an SNA type 2.0 node or an APPN node
          acting in the role of a Dependent LU Requester (DLUR).

          Host and gateway TN3270E server implementations typically
          differ greatly as to their internal implementation and
          system definition (SYSDEF) requirements."
      ::= { tn3270eSrvrConfEntry 10 }

Okay so the session-termination knob is honestly iconic πŸŽ€ terminate(1) just hangs up, luSessionPend(2) keeps the TCP connection alive and redrives session init like the client just showed up πŸ¦‹, and queueSession(3) is the CLSDST PASS drama where the connection waits around for the BIND from APPL2 πŸ“ The host vs gateway split is giving "where does the SSCP live" and it's a whole vibe 🌸

  tn3270eSrvrConfContact OBJECT-TYPE
      SYNTAX      SnmpAdminString
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION
          "This object provides a scratch pad for a TN3270E
          server administrator for storing information for
          later retrieval."
      DEFVAL { ''H }   -- the empty string
      ::= { tn3270eSrvrConfEntry 11 }

  tn3270eSrvrConfRowStatus OBJECT-TYPE
      SYNTAX      RowStatus
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION
          "This object allows entries to be created and deleted
          in the tn3270eSrvrConfTable.  Entries may also be
          created and deleted as a result of implementation-
          dependent operations.

          With the exception of tn3270eSrvrConfSrvrType, which
          an implementation can easily fill in for itself, all
          the columnar objects in this table have DEFVALs
          associated with them.  Consequently, a Management
          Station can create a conceptual row via a SET
          operation that specifies a value only for this object.

          When a tn3270eSrvrConfEntry is deleted (by setting
          this object to destroy(6)), this has the side-effect
          of removing all the associated entries (i.e., those
          having the same tn3270eSrvrConfIndex) from the
          tn3270eSrvrPortTable, the tn3270eSrvrStatsTable, the
          tn3270eClientGroupTable, the tn3270eResPoolTable,
          the tn3270eSnaMapTable, the tn3270eClientResMapTable,
          and the tn3270eResMapTable.  All entries in the
          tn3270eTcpConnTable that belong to a TN3270E server
          that has been deleted MUST also be removed.

          In other words, a tn3270eSrvrConfEntry must exist for
          a TN3270E server in order for it to have entries in
          any of the other tables defined by this MIB."
      REFERENCE
          "RFC 1903, 'Textual Conventions for version 2 of the
          Simple Network Management Protocol (SNMPv2).'"
      ::= { tn3270eSrvrConfEntry 12 }

  tn3270eSrvrConfLastActTime OBJECT-TYPE
      SYNTAX      DateAndTime
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object reports the DateAndTime when a TN3270E
          server was most recently activated.

          The special value of all '00'Hs indicates that the
          server has never been active, i.e., that the value of
          tn3270eSrvrOperStatus has never been anything other
          than down(2)."
      DEFVAL { '0000000000000000'H }
      ::= { tn3270eSrvrConfEntry 13 }

  tn3270eSrvrConfTmTimeout OBJECT-TYPE
      SYNTAX      Unsigned32 (1..600) -- 1 second to 10 minutes
      UNITS "seconds"
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION
         "The TIMING-MARK time-out, specified in seconds."
      DEFVAL { 5 }   -- 5 seconds
      ::= { tn3270eSrvrConfEntry 14 }

Ngl the RowStatus one is the main character of this whole chunk πŸ‘‘ Deleting a conf row cascades and wipes all its buddies from the other tables, and the MUST in there is not up for debate πŸ™ˆ Also tn3270eSrvrConfLastActTime defaults to all zeros, which just means "never been active" and that's so relatable tbh 🧚 The timing-mark timeout is 5 seconds by default and can go anywhere from 1 second to 10 minutes ⏰

  tn3270eSrvrPortTable OBJECT-TYPE
      SYNTAX      SEQUENCE OF Tn3270eSrvrPortEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "This table defines the TCP ports associated with
          TN3270E servers.  No entry in this table shall exist
          without a corresponding (same tn3270eSrvrConfIndex)
          entry in the tn3270eSrvrConfTable existing.

          An implementation SHOULD NOT retain SNMP-created
          entries in this table across re-IPLs (Initial Program
          Loads) of the corresponding TN3270E server."
      ::= { tn3270eObjects 2 }

  tn3270eSrvrPortEntry OBJECT-TYPE
      SYNTAX      Tn3270eSrvrPortEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "Definition of a single TCP port assignment to a
           TN3270E server.  Assignment of a port on a local
           address basis is enabled though use of
           tn3270eSrvrPortAddrType and tn3270eSrvrPortAddress.

           A TCP port assignment that is not restricted to
           a local address SHALL specify a tn3270eSrvrPortAddrType
           of unknown(0), and SHALL use a zero-length octet string
           for the tn3270eSrvrPortAddress."
      INDEX       {
                    tn3270eSrvrConfIndex,
                    tn3270eSrvrPort,
                    tn3270eSrvrPortAddrType,
                    tn3270eSrvrPortAddress
                  }
      ::= { tn3270eSrvrPortTable 1 }

  Tn3270eSrvrPortEntry ::= SEQUENCE {
      tn3270eSrvrPort                 Unsigned32,
      tn3270eSrvrPortAddrType         IANATn3270eAddrType,
      tn3270eSrvrPortAddress          IANATn3270eAddress,
      tn3270eSrvrPortRowStatus        RowStatus
    }

  tn3270eSrvrPort OBJECT-TYPE
      SYNTAX      Unsigned32 (0..65535)
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
         "Indicates a port assigned to a server."
      ::= { tn3270eSrvrPortEntry 1 }

  tn3270eSrvrPortAddrType OBJECT-TYPE
      SYNTAX      IANATn3270eAddrType
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "Indicates the type of an address local to the host on
          which the TN3270E server resides that is represented
          in tn3270eSrvrPortAddress.  A value of unknown(0)
          SHALL be used for this object when the port is not
          to be restricted to a local address."
      ::= { tn3270eSrvrPortEntry 2 }

  tn3270eSrvrPortAddress OBJECT-TYPE
      SYNTAX      IANATn3270eAddress
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "A local address on the host that a TN3270E server
           resides on that is associated with a TCP port that
           is to be used or is in use by a TN3270E server.
           tn3270eClientGroupAddrType indicates the
           address type (IPv4 or IPv6, for example).

           A zero-length octet string SHALL be used as the
           value of this object when a local address isn't
           being specified."
      ::= { tn3270eSrvrPortEntry 3 }

  tn3270eSrvrPortRowStatus OBJECT-TYPE
      SYNTAX      RowStatus
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION
          "This object allows entries to be created and deleted
          in the tn3270eSrvrPortTable.  Entries may also be
          created and deleted as a result of implementation-
          dependent operations.

          Since this is the only accessible object in this table,
          a Management Station can create a conceptual row via a SET
          operation that specifies a value only for this object.

          An entry in this table is deleted by setting this object
          to destroy(6).  Deletion of a tn3270eSrvrPortEntry has
          no effect on any other table entry defined by this MIB."
      REFERENCE
          "RFC 1903, 'Textual Conventions for version 2 of the
          Simple Network Management Protocol (SNMPv2).'"
      ::= { tn3270eSrvrPortEntry 4 }

The port table is all about the index crew πŸ¦‹ Each port can be pinned to a local address or left wide open, and the wide-open version uses unknown(0) with a zero-length string, which is giving "no preferences, just vibes" 🌈 Also heads up, the table is NOT supposed to keep SNMP-made entries across re-IPLs, so don't get attached to them πŸ’€ Deleting a port row doesn't touch anything else in the MIB, which is honestly very healthy boundaries 🫢

  tn3270eSrvrStatsTable OBJECT-TYPE
      SYNTAX      SEQUENCE OF Tn3270eSrvrStatsEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "This table defines a set of statistics concerning
          TN3270E server performance.

          No entry in this table shall exist without
          a corresponding (same tn3270eSrvrConfIndex) entry in
          the tn3270eSrvrConfTable existing."
      ::= { tn3270eObjects 3 }

  tn3270eSrvrStatsEntry OBJECT-TYPE
      SYNTAX      Tn3270eSrvrStatsEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "A collection of statistical and maximum usage objects
          for a single TN3270 server.  An entry can represent the total
          activity of the server, or it can represent the activity
          occurring at the server on either a port or a
          port-and-local-address basis.

Okay so this is where the stats table gets real πŸ“Š Collecting these numbers is totally not mandatory, bestie πŸ’…, but if you do track them, an implementation MUST use only one of the three levels of refinement for the entries tied to each TN3270E server. No mixing levels for the same server πŸ™…β€β™€οΈ

Here's how the index for each row works at each level:

          Server-wide (total server statistics):

               tn3270eSrvrConfIndex      value identifying the server
               tn3270eSrvrPort           0
               tn3270eSrvrPortAddrType   unknown(0)
               tn3270eSrvrPortAddress    zero-length octet string.

          On a port basis:

               tn3270eSrvrConfIndex      value identifying the server
               tn3270eSrvrPort           > 0
               tn3270eSrvrPortAddrType   unknown(0)
               tn3270eSrvrPortAddress    zero-length octet string.

          On a port-and-local-address basis:

               tn3270eSrvrConfIndex      value identifying the server
               tn3270eSrvrPort           > 0
               tn3270eSrvrPortAddrType   valid value other than unknown(0)
               tn3270eSrvrPortAddress    non-zero-length octet string.

Wait, I need to keep this exact, so the layout headers above are my own labels. Let me say it plainly: the total server row uses port 0 with a zero-length address, the port row uses a port above 0 with an unknown address type, and the port-and-local-address row uses a port above 0 with a real address type and a non-zero-length address ✨

Now the index and the entry layout:

      INDEX       {
                    tn3270eSrvrConfIndex,
                    tn3270eSrvrPort,
                    tn3270eSrvrPortAddrType,
                    tn3270eSrvrPortAddress

                  }
      ::= { tn3270eSrvrStatsTable 1 }

  Tn3270eSrvrStatsEntry ::= SEQUENCE {
      tn3270eSrvrStatsUpTime          TimeStamp,
      tn3270eSrvrStatsMaxTerms        Unsigned32,
      tn3270eSrvrStatsInUseTerms      Gauge32,
      tn3270eSrvrStatsSpareTerms      Gauge32,
      tn3270eSrvrStatsMaxPtrs         Unsigned32,
      tn3270eSrvrStatsInUsePtrs       Gauge32,
      tn3270eSrvrStatsSparePtrs       Gauge32,
      tn3270eSrvrStatsInConnects      Counter32,
      tn3270eSrvrStatsConnResrceRejs  Counter32,
      tn3270eSrvrStatsDisconnects     Counter32,
      tn3270eSrvrStatsHCInOctets      Counter64,
      tn3270eSrvrStatsInOctets        Counter32,
      tn3270eSrvrStatsHCOutOctets     Counter64,
      tn3270eSrvrStatsOutOctets       Counter32,
      tn3270eSrvrStatsConnErrorRejs   Counter32
    }

Here comes the big stats crew, one object at a time πŸŽ€ First up is the uptime, which is basically the server's birthday timestamp πŸŽ‚

  tn3270eSrvrStatsUpTime OBJECT-TYPE
      SYNTAX      TimeStamp
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "The value of the sysUpTime object the last time
          the TN3270E server was re-initialized.

          Server re-initialization is the only discontinuity
          event for the counters in this table.  Even if table
          entries are on a port or port-and-local-address
          basis, port deactivation and reactivation do not
          result in counter discontinuities."
      ::= { tn3270eSrvrStatsEntry 2 }

Next, the max terminal LUs, which is the ceiling of how many terminals the server can hand out πŸ–₯️

  tn3270eSrvrStatsMaxTerms OBJECT-TYPE
      SYNTAX      Unsigned32
      UNITS       "LUs"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
         "Indicates the maximum number of terminal LUs available
         for use at a TN3270E server for the granularity of this
         conceptual row (server-wide, port, or
         port-and-local-address)."
      ::= { tn3270eSrvrStatsEntry 3 }

In-use terminal LUs is how many are currently busy πŸ’Ό

  tn3270eSrvrStatsInUseTerms OBJECT-TYPE
      SYNTAX      Gauge32
      UNITS       "LUs"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
         "Indicates the number of terminal LUs currently in
         use at a TN3270E server for the granularity of this
         conceptual row (server-wide, port, or
         port-and-local-address)."
      ::= { tn3270eSrvrStatsEntry 4 }

Spare terminal LUs is the free ones, but ngl there's a twist: the math doesn't always add up πŸ‘€

  tn3270eSrvrStatsSpareTerms OBJECT-TYPE
      SYNTAX      Gauge32
      UNITS       "LUs"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
         "Indicates the number of free terminal LUs at a TN3270E
         server for the granularity of this conceptual row
         (server-wide, port, or port-and-local-address).

         It is possible that the difference between
         tn3270eSrvrStatsMaxTerms and tn3270eSrvrStatsInUseTerms
         in a conceptual row does not equal the value of
         tn3270eSrvrStatsSpareTerms in that row:  an LU may
         exist but not be usable by a client connection.

         Alternatively, the administrative ceiling represented
         by tn3270eSrvrStatsMaxTerms may have been lowered to
         a point where it is less than the current value of
         tn3270eSrvrStatsInUseTerms.  In this case
         tn3270eSrvrStatsSpareTerms returns the value 0."

      ::= { tn3270eSrvrStatsEntry 5 }

Printer resources get the same treatment as terminals, just with their own units πŸ–¨οΈβœ¨

  tn3270eSrvrStatsMaxPtrs OBJECT-TYPE
      SYNTAX      Unsigned32
      UNITS       "Printer Resources"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
         "Indicates the maximum number of printer resources
         available for use by a TN3270E server for the
         granularity of this conceptual row (server-wide,
         port, or port-and-local-address)."
      ::= { tn3270eSrvrStatsEntry 6 }
  tn3270eSrvrStatsInUsePtrs OBJECT-TYPE
      SYNTAX      Gauge32
      UNITS       "Printer Resources"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
         "Indicates the number of printer resources
         currently in use by a TN3270E server for the
         granularity of this conceptual row (server-wide,
         port, or port-and-local-address)."
      ::= { tn3270eSrvrStatsEntry 7 }
  tn3270eSrvrStatsSparePtrs OBJECT-TYPE
      SYNTAX      Gauge32
      UNITS       "Spare Printer Resources"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
         "Indicates the number of free printer resources at
         a TN3270E server for the granularity of this conceptual
         row (server-wide, port, or port-and-local-address).

         It is possible that the difference between
         tn3270eSrvrStatsMaxPtrs and tn3270eSrvrStatsInUsePtrs
         in a conceptual row does not equal the value of
         tn3270eSrvrStatsSparePtrs in that row:  a printer
         resource may exist but not be usable by a client
         connection.

         Alternatively, the administrative ceiling represented
         by tn3270eSrvrStatsMaxPtrs may have been lowered to
         a point where it is less than the current value of
         tn3270eSrvrStatsInUsePtrs.  In this case
         tn3270eSrvrStatsSparePtrs returns the value 0."
      ::= { tn3270eSrvrStatsEntry 8 }

Now the connection counters, which are where the drama is πŸ“ž

  tn3270eSrvrStatsInConnects OBJECT-TYPE
      SYNTAX      Counter32
      UNITS       "connections"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
         "Indicates the number of client (TCP) connections
         that succeeded at a TN3270E server for the
         granularity of this conceptual row (server-wide,
         port, or port-and-local-address).

         The tn3270eSrvrStatsConnResrceRejs and
         tn3270eSrvrStatsConnErrorRejs objects provide a count
         of failed connection attempts.

         A Management Station can detect discontinuities in
         this counter by monitoring the tn3270eSrvrStatsUpTime
         object."
      ::= { tn3270eSrvrStatsEntry 9 }

Rejected for lack of resources vs. rejected for errors. Two different sad stories 😭

  tn3270eSrvrStatsConnResrceRejs OBJECT-TYPE
      SYNTAX      Counter32
      UNITS       "connection attempts"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
         "Indicates the number of (TCP) connections rejected
         during connection setup at a TN3270E server for the
         granularity of this conceptual row (server-wide,
         port, or port-and-local-address) due to a lack of
         resources at the server.  An example of when this
         counter would be incremented is when no terminal
         or printer resource is available to associate with a
         client's TCP connection.

         A Management Station can detect discontinuities in
         this counter by monitoring the tn3270eSrvrStatsUpTime
         object."
      ::= { tn3270eSrvrStatsEntry 10 }
  tn3270eSrvrStatsDisconnects OBJECT-TYPE
      SYNTAX      Counter32
      UNITS       "disconnections"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
         "Indicates the number of (TCP) connections that were
         disconnected at a TN3270E server for the
         granularity of this conceptual row (server-wide,
         port, or port-and-local-address).

         A Management Station can detect discontinuities in
         this counter by monitoring the tn3270eSrvrStatsUpTime
         object."
      ::= { tn3270eSrvrStatsEntry 11 }

Octet counters next, with the 64-bit ones as the main characters and the 32-bit ones as their low-order sidekicks πŸ’œ

  tn3270eSrvrStatsHCInOctets OBJECT-TYPE
      SYNTAX      Counter64
      UNITS       "octets"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
         "Indicates the number of octets received from TN3270
         and TN3270E clients for the granularity of this
         conceptual row (server-wide, port, or
         port-and-local-address).

         A Management Station can detect discontinuities in
         this counter by monitoring the tn3270eSrvrStatsUpTime
         object."
      ::= { tn3270eSrvrStatsEntry 12 }
  tn3270eSrvrStatsInOctets OBJECT-TYPE
      SYNTAX      Counter32
      UNITS       "octets"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
         "Low-order 32 bits of tn3270eSrvrStatsHCInOctets for
         this conceptual row.

         A Management Station can detect discontinuities in
         this counter by monitoring the tn3270eSrvrStatsUpTime
         object."
      ::= { tn3270eSrvrStatsEntry 13 }
  tn3270eSrvrStatsHCOutOctets OBJECT-TYPE
      SYNTAX      Counter64
      UNITS       "octets"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
         "Indicates the number of octets sent to TN3270
         and TN3270E clients for the granularity of this
         conceptual row (server-wide, port, or
         port-and-local-address).

         A Management Station can detect discontinuities in
         this counter by monitoring the tn3270eSrvrStatsUpTime
         object."
      ::= { tn3270eSrvrStatsEntry 14 }
  tn3270eSrvrStatsOutOctets OBJECT-TYPE
      SYNTAX      Counter32
      UNITS       "octets"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION

         "Low-order 32 bits of tn3270eSrvrStatsHCOutOctets for
         this conceptual row.

         A Management Station can detect discontinuities in
         this counter by monitoring the tn3270eSrvrStatsUpTime
         object."
      ::= { tn3270eSrvrStatsEntry 15 }

Last stat in this table: the error rejections, which happen when the client and server can't agree on TN3270E functions πŸ™ƒ

  tn3270eSrvrStatsConnErrorRejs OBJECT-TYPE
      SYNTAX      Counter32
      UNITS       "connection attempts"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
         "Indicates the number of (TCP) connections rejected
         during connection setup at a TN3270E server for the
         granularity of this conceptual row (server-wide,
         port, or port-and-local-address) due to an error
         of some type.  An example of when this counter would
         be incremented is when the client and the server
         cannot agree on a common set of TN3270E functions for
         the connection.

         A Management Station can detect discontinuities in
         this counter by monitoring the tn3270eSrvrStatsUpTime
         object."
      ::= { tn3270eSrvrStatsEntry 16 }

And now we're on to the client group table, which is where the next chapter starts 🧚

  tn3270eClientGroupTable OBJECT-TYPE
      SYNTAX      SEQUENCE OF Tn3270eClientGroupEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "This table defines client address groupings for use
          by a TN3270E server.

          No entry in this table shall exist without
          a corresponding (same tn3270eSrvrConfIndex) entry in
          the tn3270eSrvrConfTable existing.

Okay so this bit picks up right where the last table left off, and it's all about when SNMP-made rows are allowed to stick around πŸŽ€

          An implementation SHOULD NOT retain SNMP-created
          entries in this table across re-IPLs (Initial Program
          Loads) of the corresponding TN3270E server."
      ::= { tn3270eObjects 4 }

Next up is the client group entry, the row that says which client addresses belong together 🫢 Every row with the same first two indexes is in the same group, bestie ✨

  tn3270eClientGroupEntry OBJECT-TYPE
      SYNTAX      Tn3270eClientGroupEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "Definition of a single client address entry.  All
          entries with the same first two indexes,
          tn3270eSrvrConfIndex and tn3270eClientGroupName, are
          considered to be in the same client group."
      INDEX       { tn3270eSrvrConfIndex,
                    tn3270eClientGroupName,
                    tn3270eClientGroupAddrType,
                    tn3270eClientGroupAddress }
      ::= { tn3270eClientGroupTable 1 }

  Tn3270eClientGroupEntry ::= SEQUENCE {
      tn3270eClientGroupName           Utf8String,
      tn3270eClientGroupAddrType       IANATn3270eAddrType,
      tn3270eClientGroupAddress        IANATn3270eAddress,
      tn3270eClientGroupSubnetMask     IpAddress,
      tn3270eClientGroupPfxLength      Unsigned32,
      tn3270eClientGroupRowStatus      RowStatus
  }

  tn3270eClientGroupName OBJECT-TYPE
      SYNTAX      Utf8String (SIZE(1..24))
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "The name of a client group.  Note: client group
          names are required to be unique only with respect
          to a single TN3270E server."
      ::= { tn3270eClientGroupEntry 1 }

The group name is only unique inside one server, so two servers can each have a "group" with the same name and nobody gets confused πŸ’…

  tn3270eClientGroupAddrType OBJECT-TYPE
      SYNTAX      IANATn3270eAddrType
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "Indicates the type of the address represented in
           tn3270eClientGroupAddress."
      ::= { tn3270eClientGroupEntry 2 }

  tn3270eClientGroupAddress OBJECT-TYPE
      SYNTAX      IANATn3270eAddress
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "The client address of a member of a client group.
          The value of tn3270eClientGroupAddrType indicates
          the address type (IPv4 or IPv6, for example)."

      ::= { tn3270eClientGroupEntry 3 }

So the AddrType is the "what kind of address is this" flag, and the address is the actual address, the IPv4 or IPv6 one πŸ¦‹

  tn3270eClientGroupSubnetMask OBJECT-TYPE
      SYNTAX      IpAddress
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION
          "The corresponding subnet mask associated with
           tn3270eClientGroupAddress.  A single IP address is
           represented by having this object contain the value
           of 255.255.255.255.

           This object's value is meaningful only if
           tn3270eClientGroupAddrType has a value of ipv4(1)."
      DEFVAL { 'FFFFFFFF'H }
      ::= { tn3270eClientGroupEntry 4 }

  tn3270eClientGroupPfxLength OBJECT-TYPE
      SYNTAX      Unsigned32 (0..128)
      UNITS       "bits"
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION
          "The corresponding IPv6 network prefix length.

          This object's value is meaningful only if
          tn3270eClientGroupAddrType  has a value of ipv6(2)."
      DEFVAL { 0 }
      ::= { tn3270eClientGroupEntry 5 }

The subnet mask only matters for IPv4 and the prefix length only matters for IPv6, so each one ignores the other's type 🌈

  tn3270eClientGroupRowStatus OBJECT-TYPE
      SYNTAX      RowStatus
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION
          "This object allows entries to be created and deleted
          in the tn3270eClientGroupTable.  Entries may also be
          created and deleted as a result of implementation-
          dependent operations.

          An entry in this table is deleted by setting this object
          to destroy(6).  When the number of entries in this table
          for a given client group becomes 0, this has the side-
          effect of removing any entries for the group in the
          tn3270eClientResMapTable."
      REFERENCE
          "RFC 1903, 'Textual Conventions for version 2 of the
          Simple Network Management Protocol (SNMPv2).'"

      ::= { tn3270eClientGroupEntry 6 }

Setting the row status to destroy(6) is how you delete an entry πŸ’€ And when a group runs out of entries, its mappings in the resource map table get cleaned up too, which is so iconic of it πŸ‘‘

  tn3270eResPoolTable OBJECT-TYPE
      SYNTAX      SEQUENCE OF Tn3270eResPoolEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "This table defines resource groupings; the term
          'pool' is used as it is defined by RFC 2355.

          No entry in this table shall exist without
          a corresponding (same tn3270eSrvrConfIndex) entry in
          the tn3270eSrvrConfTable existing.

          An implementation SHOULD NOT retain SNMP-created
          entries in this table across re-IPLs (Initial Program
          Loads) of the corresponding TN3270E server."
      ::= { tn3270eObjects 5 }

  tn3270eResPoolEntry OBJECT-TYPE
      SYNTAX      Tn3270eResPoolEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "Definition of a single resource pool member.  All entries
          with the same first two indexes, tn3270eSrvrConfIndex and
          tn3270eResPoolName, are considered to be in the same pool."
      INDEX  { tn3270eSrvrConfIndex,
               tn3270eResPoolName,
               tn3270eResPoolElementName }
      ::= { tn3270eResPoolTable 1 }

  Tn3270eResPoolEntry ::= SEQUENCE {
      tn3270eResPoolName           Utf8String,
      tn3270eResPoolElementName    SnaResourceName,
      tn3270eResPoolElementType    IANATn3270ResourceType,
      tn3270eResPoolRowStatus      RowStatus
  }

Resource pools are the groupings of resources, and the word "pool" borrows its meaning from RFC 2355, so go check that one too 🧚

  tn3270eResPoolName OBJECT-TYPE
      SYNTAX      Utf8String (SIZE(1..24))
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "The name of a resource pool."
      ::= { tn3270eResPoolEntry 1 }

  tn3270eResPoolElementName OBJECT-TYPE

      SYNTAX      SnaResourceName
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "The name of a member of a resource pool."
      ::= { tn3270eResPoolEntry 2 }

  tn3270eResPoolElementType OBJECT-TYPE
      SYNTAX      IANATn3270ResourceType
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION
          "The type of the entity in a resource pool."
      ::= { tn3270eResPoolEntry 3 }

  tn3270eResPoolRowStatus OBJECT-TYPE
      SYNTAX      RowStatus
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION
          "This object allows entries to be created and deleted
          in the tn3270eResPoolTable.  Entries may also be
          created and deleted as a result of implementation-
          dependent operations.

          An entry in this table is deleted by setting this object
          to destroy(6).  When all entries in this table associated
          with the same tn3270eResPoolElementName have been removed,
          then any associated (tn3270eResPoolElementName matching
          tn3270eClientResMapPoolName with same tn3270eSrvrConfIndex
          values) entries in the tn3270eClientResMapTable SHALL
          also be removed."
      REFERENCE
          "RFC 1903, 'Textual Conventions for version 2 of the
          Simple Network Management Protocol (SNMPv2).'"
      ::= { tn3270eResPoolEntry 4 }

Here the rule is a hard one. Once every row for a given element name is gone, the matching client-to-pool mappings have to go too, and that one's a must, not a maybe πŸ”₯

  tn3270eSnaMapTable OBJECT-TYPE
      SYNTAX      SEQUENCE OF Tn3270eSnaMapEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "This table provide a mapping from the name by which
          a secondary LU is known in the SNA network to the
          name by which it is known locally at the TN3270e
          server.  This latter name serves as an index into
          the tn3270eResPoolTable and the tn3270eResMapTable.

          No entry in this table shall exist without
          a corresponding (same tn3270eSrvrConfIndex) entry in
          the tn3270eSrvrConfTable existing."
      ::= { tn3270eObjects 6 }

  tn3270eSnaMapEntry OBJECT-TYPE
      SYNTAX      Tn3270eSnaMapEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "Definition of a single mapping from an SSCP-supplied
          SLU name to a local SLU name.

          Note:  In certain pathological cases, it is possible
          that an SSCP will send on an ACTLU for a local LU an
          SLU name currently represented by an entry in this
          table that associates it with a different local LU.
          In these cases the association from the newer ACTLU
          SHOULD be the one represented in this table."
      INDEX  { tn3270eSrvrConfIndex,
               tn3270eSnaMapSscpSuppliedName }
      ::= { tn3270eSnaMapTable 1 }

  Tn3270eSnaMapEntry ::= SEQUENCE {
      tn3270eSnaMapSscpSuppliedName     SnaResourceName,
      tn3270eSnaMapLocalName            SnaResourceName,
      tn3270eSnaMapPrimaryLuName        SnaResourceName
  }

The SNA map is the name translator for secondary LUs, and the edge case in the SnaMapEntry note is a total plot twist 😭 If the SSCP sends a conflicting ACTLU, the newer association is the one that should show up in the table.

  tn3270eSnaMapSscpSuppliedName OBJECT-TYPE
      SYNTAX      SnaResourceName
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "The name of the secondary LU (SLU) as it is known in
           the SNA network.  This name is sent by the SSCP on
           the Activate Logical Unit (ACTLU) request."
      ::= { tn3270eSnaMapEntry 1 }

  tn3270eSnaMapLocalName OBJECT-TYPE
      SYNTAX      SnaResourceName
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "The local name of the secondary LU (SLU)."
      ::= { tn3270eSnaMapEntry 2 }

  tn3270eSnaMapPrimaryLuName  OBJECT-TYPE

      SYNTAX   SnaResourceName
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "When there is a currently active LU-LU session for
          this connection, this object returns the primary LU
          (PLU) name from the BIND.  When there is no active
          LU-LU session, or when the PLU name is unavailable
          for some other reason, this object returns a
          zero-length octet string."
      ::= { tn3270eSnaMapEntry 3 }

The primary LU name is only filled in while a session is live, and otherwise you get an empty string, which is a very chill way to say "nothing here yet" πŸ“

  tn3270eClientResMapTable OBJECT-TYPE
      SYNTAX      SEQUENCE OF Tn3270eClientResMapEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "This table defines resource-pool to client-group
          mappings.  Since both the resource pool name and client
          group name are included in the index clause of this
          table, multiple resource pools can be assigned to the
          same client group.  This enables use of multiple
          resource pools for use in client to resource mapping.
          Assigning multiple client groups to the same resource
          pool is also allowed, but is not the primary purpose
          for how the indexing is structured.

          Assignment of a resource pool to client group can be
          restricted based on TCP port.  An index value of 0 for
          tn3270eClientResMapClientPort disables restriction of
          resource assignment based on client target port
          selection.

          No entry in this table shall exist without
          a corresponding (same tn3270eSrvrConfIndex) entry in
          the tn3270eSrvrConfTable existing.

          An implementation SHOULD NOT retain SNMP-created
          entries in this table across re-IPLs (Initial Program
          Loads) of the corresponding TN3270E server."
      ::= { tn3270eObjects 7 }

  tn3270eClientResMapEntry OBJECT-TYPE
      SYNTAX      Tn3270eClientResMapEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "Definition of a single resource pool to client group
          mapping."
      INDEX  { tn3270eSrvrConfIndex,
               tn3270eClientResMapPoolName,
               tn3270eClientResMapClientGroupName,
               tn3270eClientResMapClientPort }
      ::= { tn3270eClientResMapTable 1 }

  Tn3270eClientResMapEntry ::= SEQUENCE {
      tn3270eClientResMapPoolName           Utf8String,
      tn3270eClientResMapClientGroupName    Utf8String,
      tn3270eClientResMapClientPort         Unsigned32,
      tn3270eClientResMapRowStatus          RowStatus
  }

The client-to-resource map is where pools and client groups finally meet πŸ¦‹ Because both names sit in the index, one pool can serve several groups, and the port value of 0 switches off the port restriction, which is giving flexible πŸ’œ

okay bestie, we're picking up right in the middle of the client resource map definitions πŸ§šπŸ’– this part is all MIB code, so every line stays exactly as written, but the vibes around it are literally unmatched ✨

  tn3270eClientResMapPoolName OBJECT-TYPE
      SYNTAX      Utf8String (SIZE(1..24))
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "The name of a resource pool."
      ::= { tn3270eClientResMapEntry 1 }

  tn3270eClientResMapClientGroupName OBJECT-TYPE
      SYNTAX      Utf8String (SIZE(1..24))
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "The name of the client group that is mapped to a
           resource pool."
      ::= { tn3270eClientResMapEntry 2 }

  tn3270eClientResMapClientPort OBJECT-TYPE
      SYNTAX      Unsigned32 (0..65535)
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "A port number restricting the scope of a mapping
          from a resource pool to a client group.  The
          value 0 for this object indicates that the scope
          of the mapping is not restricted."
      ::= { tn3270eClientResMapEntry 3 }

  tn3270eClientResMapRowStatus OBJECT-TYPE
      SYNTAX      RowStatus
      MAX-ACCESS  read-create
      STATUS      current
      DESCRIPTION
          "This object allows entries to be created and deleted
          in the tn3270eClientResMapTable.  Entries may also be
          created and deleted as a result of implementation-
          dependent operations.

          An entry in this table is deleted by setting this object
          to destroy(6).  Removing an entry from this table doesn't
          affect any other table entry defined in this MIB."
      REFERENCE
          "RFC 1903, 'Textual Conventions for version 2 of the
          Simple Network Management Protocol (SNMPv2).'"
      ::= { tn3270eClientResMapEntry 4 }

  tn3270eResMapTable OBJECT-TYPE
      SYNTAX      SEQUENCE OF Tn3270eResMapEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "This table defines the actual mapping of a resource
          to a client address.

          No entry in this table shall exist without
          a corresponding (same tn3270eSrvrConfIndex) entry in
          the tn3270eSrvrConfTable existing."
      ::= { tn3270eObjects 8 }

  tn3270eResMapEntry OBJECT-TYPE
      SYNTAX      Tn3270eResMapEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "Definition of the mapping of a Resource Element to
           a client address."
      INDEX  { tn3270eSrvrConfIndex,
               tn3270eResMapElementName }
      ::= { tn3270eResMapTable 1 }

  Tn3270eResMapEntry ::= SEQUENCE {
      tn3270eResMapElementName       SnaResourceName,
      tn3270eResMapAddrType          IANATn3270eAddrType,
      tn3270eResMapAddress           IANATn3270eAddress,
      tn3270eResMapPort              Unsigned32,
      tn3270eResMapElementType       IANATn3270ResourceType,
      tn3270eResMapSscpSuppliedName  SnaResourceName
  }

  tn3270eResMapElementName OBJECT-TYPE
      SYNTAX      SnaResourceName
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "The name of a resource element.  This is the name by
          which the server implementing this table knows the
          resource.  It may be different from the name by which
          the resource is known in the SNA network.  This latter
          name is returned in the tn3270eResMapSscpSuppliedName
          object."
      ::= { tn3270eResMapEntry 1 }

  tn3270eResMapAddrType OBJECT-TYPE
      SYNTAX      IANATn3270eAddrType
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "Indicates the type of the client address represented
          in tn3270eResMapAddress."
      ::= { tn3270eResMapEntry 2 }

  tn3270eResMapAddress OBJECT-TYPE
      SYNTAX      IANATn3270eAddress
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "A client address."
      ::= { tn3270eResMapEntry 3 }

  tn3270eResMapPort OBJECT-TYPE
      SYNTAX      Unsigned32 (0..65535)
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "A client port."
      ::= { tn3270eResMapEntry 4 }

  tn3270eResMapElementType OBJECT-TYPE
      SYNTAX      IANATn3270ResourceType
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "The type of the associated resource element."
      ::= { tn3270eResMapEntry 5 }

  tn3270eResMapSscpSuppliedName OBJECT-TYPE
      SYNTAX      SnaResourceName
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION

          "The name of the secondary LU (SLU) as it is known
          in a SNA network.  This name is sent by the SSCP on
          the Activate Logical Unit (ACTLU) request.  If this
          name is not known, this object returns a zero-length
          octet string."
      ::= { tn3270eResMapEntry 6 }

  -- Define the set of objects to supplement the TCP Connection Table

  tn3270eTcpConnTable OBJECT-TYPE
      SYNTAX SEQUENCE OF Tn3270eTcpConnEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
           "This table has an entry for each TN3270(E) client
           connection that is currently active at a TN3270E server.
           An implementation MAY retain entries for connections
           that have been terminated, but which entries are
           retained, how many entries are retained, and how long
           they are retained is entirely implementation-dependent.

           The indexing for this table is designed to support the
           use of an SNMP GET-NEXT operation using only the remote
           address type, remote address, and remote port, as a way
           for a Management Station to retrieve the table entries
           related to a particular TN3270(E) client."
      ::= { tn3270eObjects 9 }

  tn3270eTcpConnEntry OBJECT-TYPE
      SYNTAX Tn3270eTcpConnEntry
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "Provides information about a single TN3270/TN3270E
          session.  Note: a tn3270eSrvrConfIndex is not needed
          in this table, since the combination of remote and
          local addresses and ports is sufficient to
          guarantee uniqueness across the TN3270E servers
          serviced by an SNMP agent.  Because of this indexing
          structure, however, this table does not support
          view-based access control policies that provide
          access to table rows on a per-server basis."
      INDEX { tn3270eTcpConnRemAddrType,
              tn3270eTcpConnRemAddress,
              tn3270eTcpConnRemPort,
              tn3270eTcpConnLocalAddrType,
              tn3270eTcpConnLocalAddress,
              tn3270eTcpConnLocalPort

            }
      ::= { tn3270eTcpConnTable 1 }

  Tn3270eTcpConnEntry ::=
      SEQUENCE
      {
      tn3270eTcpConnRemAddrType          IANATn3270eAddrType,
      tn3270eTcpConnRemAddress           IANATn3270eAddress,
      tn3270eTcpConnRemPort              Unsigned32,
      tn3270eTcpConnLocalAddrType        IANATn3270eAddrType,
      tn3270eTcpConnLocalAddress         IANATn3270eAddress,
      tn3270eTcpConnLocalPort            Unsigned32,
      tn3270eTcpConnLastActivity         TimeTicks,
      tn3270eTcpConnBytesIn              Counter32,
      tn3270eTcpConnBytesOut             Counter32,
      tn3270eTcpConnResourceElement      SnaResourceName,
      tn3270eTcpConnResourceType         IANATn3270ResourceType,
      tn3270eTcpConnDeviceType           IANATn3270DeviceType,
      tn3270eTcpConnFunctions            IANATn3270Functions,
      tn3270eTcpConnId                   Unsigned32,
      tn3270eTcpConnClientIdFormat       IANATn3270eClientType,
      tn3270eTcpConnClientId             OCTET STRING,
      tn3270eTcpConnTraceData            Tn3270eTraceData,
      tn3270eTcpConnLogInfo              IANATn3270eLogData,
      tn3270eTcpConnLuLuBindImage        OCTET STRING,
      tn3270eTcpConnSnaState             INTEGER,
      tn3270eTcpConnStateLastDiscReason  INTEGER,
      tn3270eTcpConnSrvrConfIndex        Unsigned32,
      tn3270eTcpConnActivationTime       TimeStamp
      }

  tn3270eTcpConnRemAddrType OBJECT-TYPE
      SYNTAX   IANATn3270eAddrType
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "Indicates the type of the value of the
          tn3270eTcpConnRemAddress object.  For example,
          ipv4(1) or ipv6(2)."
      ::= { tn3270eTcpConnEntry 1 }

  tn3270eTcpConnRemAddress OBJECT-TYPE
      SYNTAX      IANATn3270eAddress
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "The remote address associated with a TN3270E client.
           tn3270eTcpConnRemAddrType indicates the address type
           (IPv4 or IPv6, for example).

           If a TN3270(E) client is connected to its
           server via a proxy client the address represented by
           the value of this object shall be the remote client's
           address, not the proxy client's address."
      ::= { tn3270eTcpConnEntry 2 }

  tn3270eTcpConnRemPort OBJECT-TYPE
      SYNTAX      Unsigned32 (0..65535)
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "The remote port associated with a TN3270E client.  The value 0
          is used if the tn3270eTcpConnRemAddrType identifies an address
          type that does not support ports.

          If a TN3270(E) client is connected to its server via a proxy
          client, the port represented by the value of this object shall
          be the remote client's port, not the proxy client's port."
      ::= { tn3270eTcpConnEntry 3 }

  tn3270eTcpConnLocalAddrType OBJECT-TYPE
      SYNTAX   IANATn3270eAddrType
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "Indicates the type of the value of the
          tn3270eTcpConnLocalAddress object.  For example,
          ipv4(1) or ipv6(2)."
      ::= { tn3270eTcpConnEntry 4 }

  tn3270eTcpConnLocalAddress OBJECT-TYPE
      SYNTAX      IANATn3270eAddress
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "The local address associated with a TN3270E client.
           tn3270eTcpConnRemAddrType indicates the address type
           (IPv4 or IPv6, for example)."
      ::= { tn3270eTcpConnEntry 5 }

  tn3270eTcpConnLocalPort OBJECT-TYPE
      SYNTAX      Unsigned32 (1..65535)
      MAX-ACCESS  not-accessible
      STATUS      current
      DESCRIPTION
          "The remote port associated with a TN3270E client."

      ::= { tn3270eTcpConnEntry 6 }

  tn3270eTcpConnLastActivity OBJECT-TYPE
      SYNTAX   TimeTicks
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "The number of 100ths of seconds since any data was
           transferred for the associated TCP Connection."
      DEFVAL  { 0 }
      ::= { tn3270eTcpConnEntry 7 }

  tn3270eTcpConnBytesIn OBJECT-TYPE
      SYNTAX   Counter32
      UNITS "octets"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "The number of bytes received by the server from TCP
          for this connection.

          A Management Station can detect discontinuities in
          this counter by monitoring the
          tn3270eTcpConnActivationTime object."
      ::= { tn3270eTcpConnEntry 8 }

  tn3270eTcpConnBytesOut OBJECT-TYPE
      SYNTAX   Counter32
      UNITS "octets"
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "The number of bytes sent to TCP for this connection.

          A Management Station can detect discontinuities in
          this counter by monitoring the
          tn3270eTcpConnActivationTime object."
      ::= { tn3270eTcpConnEntry 9 }
the tn3270eTcpConnTable description has a capital MAY in it (so it's a real requirement, not just vibes) and the tn3270eTcpConnLocalPort description literally says "remote port", which is an original RFC quirk I've kept as-is πŸ™ˆπŸ’…

Okay bestie, we're deep in the MIB now and it's giving detailed πŸ§šπŸ’… Here's the next batch of TCP connection columns, from the resource element all the way down to the spin lock.

  tn3270eTcpConnResourceElement OBJECT-TYPE
      SYNTAX   SnaResourceName
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "LU/Print secondary name for connecting an client
           into an SNA network."
      ::= { tn3270eTcpConnEntry 10 }

  tn3270eTcpConnResourceType OBJECT-TYPE
      SYNTAX   IANATn3270ResourceType
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "Indicates the type of resource identified by
           tn3270eTcpConnResourceElement."
      ::= { tn3270eTcpConnEntry 11 }

  tn3270eTcpConnDeviceType OBJECT-TYPE
      SYNTAX   IANATn3270DeviceType
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "Indicates the device type if negotiated with the
          client.  A value of unknown(100) should be used as
          the value of this object when a device type is not
          negotiated.  Refer to RFC 2355 for how device types
          can be negotiated."
      ::= { tn3270eTcpConnEntry 12 }

So the resource element is the LU/Print secondary name that gets a client into the SNA network 🌸 The resource type tells you what kind of resource that element is ✨ And the device type is only filled in if it was actually negotiated with the client. If it wasn't, the value is unknown(100) πŸ™ˆ (and note the reference to RFC 2355 for how device types get negotiated πŸ“–)

  tn3270eTcpConnFunctions OBJECT-TYPE
      SYNTAX   IANATn3270Functions
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "This object indicates which of the TN3270 and TN3270E
          functions were negotiated by the server and the client
          for this TCP connection.

          Refer to tn3270eSrvrFunctionsSupported for the list of
          these functions supported by the server."
      ::= { tn3270eTcpConnEntry 13 }

  tn3270eTcpConnId OBJECT-TYPE
      SYNTAX      Unsigned32
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "The connection identifier associated with a TN3270 or
           a TN3270E session's TCP connection.  TCP implementations
           often assign a unique (with respect to itself) unsigned
           integer as an identifier for a TCP connection.

           The value 0 indicates that a connection does not have
           a valid connection identifier."
      ::= { tn3270eTcpConnEntry 14 }

  tn3270eTcpConnClientIdFormat OBJECT-TYPE
      SYNTAX      IANATn3270eClientType
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "The format of a corresponding tn3270eTcpConnClientId
          object as defined by the IANSTn3270eClientType textual
          convention imported from the IANATn3270eTC-MIB."
      ::= { tn3270eTcpConnEntry 15 }

  tn3270eTcpConnClientId OBJECT-TYPE
      SYNTAX      OCTET STRING (SIZE (0..512))
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "Additional client identification information.  The
          type of this information is indicated by the value of
          the corresponding tn3270eTcpConnClientIdFormat object.
          All values are returned in network-byte order.

          The purpose of this object is to provide an alternate
          means of identifying a client, other than though the
          remote address returned in tn3270eTcpConnRemAddress."
      ::= { tn3270eTcpConnEntry 16 }

This one's a vibe! πŸ’– The functions object shows which TN3270 and TN3270E functions both the server and the client agreed on for this TCP connection, and you check tn3270eSrvrFunctionsSupported to see the full list the server offers πŸŽ€ The connection id is a number TCP implementations usually hand out to each connection, and 0 means "nope, no valid id here" πŸ¦‹ The client id format tells you how to read the client id, which is extra identifying info that gives you another way to spot a client besides its remote address 🌈 All values come back in network-byte order, so keep that in mind 🫢

  tn3270eTcpConnTraceData OBJECT-TYPE
      SYNTAX   Tn3270eTraceData
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "Trace data for this session."
      ::= { tn3270eTcpConnEntry 17 }

  tn3270eTcpConnLogInfo OBJECT-TYPE
      SYNTAX      IANATn3270eLogData
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "Log information, encoded as specified in the
          IANATn3270eLogData textual convention from the
          IANAtn3270eTC-MIB."
      ::= { tn3270eTcpConnEntry 18 }

  tn3270eTcpConnLuLuBindImage  OBJECT-TYPE
      SYNTAX   OCTET STRING (SIZE (0..256))
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION

          "When there is a currently active LU-LU session for
          this connection, this object returns the BIND Image
          (defined to be bytes 1-p of the complete BIND Request
          Unit -- see 'SNA Formats' for more information)
          that was received from the PLU during session
          activation.  When there is no active LU-LU session,
          or when a BIND image is unavailable for some other
          reason, this object returns a zero-length octet
          string."
      REFERENCE
          "'Systems Network Architecture Formats', IBM
          Publication GA27-3136."
      ::= { tn3270eTcpConnEntry 19 }

Next up is the trace data for the session, plus log info encoded the way the IANA textual convention says 🧾 Then there's the LU-LU BIND image πŸ‘‘ That one's special: when there's an active LU-LU session, it hands back the BIND Image (bytes 1-p of the complete BIND Request Unit, which you can read more about in 'SNA Formats') that the PLU sent during session activation πŸ’… No active session, or no BIND image available for some other reason? You get a zero-length octet string, periodt πŸ™ˆ The reference is IBM Publication GA27-3136 πŸ“š

  tn3270eTcpConnSnaState  OBJECT-TYPE
      SYNTAX   INTEGER {
                     unknown(1),
                     noSluSession(2),
                     sscpLuSession(3),  -- but no LU-LU session
                     luLuSession(4),    -- but no SSCP-LU session
                     sscpLuSessionAndLuLuSession(5)
                        }
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "The current state of the SNA side of the end-to-end
          TN3270 connection.  The following states are defined:

              unknown(1)          - The true state is not known.
              noSluSession(2)     - The SLU has neither an SSCP-LU
                                    nor an LU-LU session active.
              sscpLuSession(3)    - The SSCP-LU session for the SLU
                                    is active, but the SLU is not
                                    currently in session with a PLU.
              luLuSession(4)      - The SLU is currently in session
                                    with a PLU, but the SSCP-LU
                                    session for the LU is not active.
              sscpLuSessionAndLuLuSession(5) - The SLU currently has
                                    an active session with a PLU,
                                    and the SSCP-LU session for the
                                    SLU is active."

      ::= { tn3270eTcpConnEntry 20 }

  tn3270eTcpConnStateLastDiscReason OBJECT-TYPE
      SYNTAX   INTEGER {
                    unknown(1),
                    hostSendsUnbind(2),
                    hostDontAcceptConnection(3),
                    outOfResource(4),
                    clientProtocolError(5),
                    invalidDeviceName(6),
                    deviceInUse(7),
                    inactivityTimeout(8),
                    hostNotResponding(9),
                    clientNotResponding(10),
                    serverClose(11),
                    sysreqLogoff(12),
                    serverSpecificHexCode(13)
                       }
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "The last disconnect reason.  A session that has not
          experienced a disconnect shall use the value unknown(1)
          for this object.  Depending on when an implementation
          removes entries from this table, certain states may
          never be returned."
      ::= { tn3270eTcpConnEntry 21 }

  tn3270eTcpConnSrvrConfIndex OBJECT-TYPE
      SYNTAX      Unsigned32 (1..4294967295)
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "tn3270eSrvrConfIndex of the tn3270eSrvrConfEntry
          belonging to the TN3270E server to which this entry
          belongs."
      ::= { tn3270eTcpConnEntry 22 }

  tn3270eTcpConnActivationTime OBJECT-TYPE
      SYNTAX      TimeStamp
      MAX-ACCESS  read-only
      STATUS      current
      DESCRIPTION
          "The value of the sysUpTime object the last time
          this TCP connection became active."
      ::= { tn3270eTcpConnEntry 23 }

  tn3270eConfSpinLock OBJECT-TYPE
      SYNTAX      TestAndIncr
      MAX-ACCESS  read-write
      STATUS      current
      DESCRIPTION
        "An advisory lock used to allow cooperating
        TN3270E-MIB applications to coordinate their use
        of the tn3270eSrvrConfTable, the tn3270eSrvrPortTable,
        the tn3270eClientGroupTable, the tn3270eResPoolTable,
        and the tn3270eClientResMapTable.

        When creating a new entry or altering an existing entry
        in the any of the tables mentioned above, an application
        should make use of tn3270eRtSpinLock to serialize
        application changes or additions.

        Since this is an advisory lock, the use of this lock is
        not enforced."
      ::= { tn3270eObjects 10 }

The SNA state is a five-way enum that tells you how the SLU is doing, from unknown(1) all the way to having both an SSCP-LU session and an LU-LU session going at once πŸ”₯ The last disconnect reason is a list of why a session dropped πŸ’€ A session that hasn't disconnected yet just uses unknown(1), and depending on when an implementation clears out table entries, some reasons might never show up 🧚 The SrvrConfIndex points back to the tn3270eSrvrConfEntry for the server this connection belongs to ✨ The activation time is the sysUpTime value from the last time the connection became active ⏰

Last but not least, tn3270eConfSpinLock is an advisory lock πŸ”’ It helps cooperating TN3270E-MIB apps coordinate changes to five tables, and before making changes they're supposed to use tn3270eRtSpinLock to serialize them 🫢 Since it's advisory, nothing actually enforces it, so it's a teamwork thing πŸ‘―β€β™€οΈ

  -- Conformance Definitions

  tn3270eGroups      OBJECT IDENTIFIER ::= { tn3270eConformance 1 }

  tn3270eCompliances OBJECT IDENTIFIER ::= { tn3270eConformance 2 }

  -- compliance statements

  tn3270eCompliance MODULE-COMPLIANCE
      STATUS      current
      DESCRIPTION
          "The compliance statement for agents that support the
          TN3270E-MIB."
      MODULE -- this module
          MANDATORY-GROUPS { tn3270eBasicGroup,
                             tn3270eSessionGroup
                           }
          GROUP       tn3270eResMapGroup
          DESCRIPTION
              "This group is optional and provides a method of
              performing tn3270eClientGroup to tn3270eResPool
              mapping."

          GROUP       tn3270eHiCapacityGroup
          DESCRIPTION
              "This group is optional and provides for support
              of high capacity counters."

          OBJECT tn3270eSrvrConfConnectivityChk
             MIN-ACCESS  read-only
             DESCRIPTION
                "The agent is not required to support a set to this
                 object if the associated TN3270E server doesn't
                 support either TIMING-MARK or NOP processing.  In
                 this case an agent should return noCheck on
                 retrieval."

          OBJECT tn3270eSrvrConfTmNopInactTime
             MIN-ACCESS  read-only
             DESCRIPTION
                "The agent is not required to support a set to this
                 object if the functions enabled by
                 tn3270eSrvrConfConnectivityChk are not supported.
                 An agent in this case should return a value of 0."

          OBJECT tn3270eSrvrConfTmNopInterval
             MIN-ACCESS  read-only
             DESCRIPTION
                "The agent is not required to support a set to this
                 object if the functions enabled by
                 tn3270eSrvrConfConnectivityChk are not supported.
                 An agent in this case should return a value of 0."

         OBJECT  tn3270eSrvrConfAdminStatus
             DESCRIPTION
                "A TN3270E server is not required to support a
                 stopImmediate state transition."

          OBJECT tn3270eSrvrConfRowStatus
             MIN-ACCESS read-only
             DESCRIPTION
                 "Write access is not required."

          OBJECT tn3270eSrvrConfTmTimeout
             MIN-ACCESS  read-only
             DESCRIPTION
                "The agent is not required to support a set to this
                 object if the functions enabled by
                 tn3270eSrvrConfConnectivityChk are not supported.
                 An agent in this case should return a value of 0."

          OBJECT tn3270eSrvrPortRowStatus
             MIN-ACCESS read-only
             DESCRIPTION
                 "Write access is not required."

          OBJECT tn3270eClientGroupRowStatus
             MIN-ACCESS read-only
             DESCRIPTION
                 "Write access is not required."

          OBJECT tn3270eResPoolRowStatus
             MIN-ACCESS read-only
             DESCRIPTION
                 "Write access is not required."

          OBJECT tn3270eClientResMapRowStatus
             MIN-ACCESS read-only
             DESCRIPTION
                 "Write access is not required."

      ::= { tn3270eCompliances 1 }

  -- units of conformance

Now we're in conformance land! πŸŽ€ The groups and compliances are just OIDs hanging off tn3270eConformance, and the big compliance statement is for agents that support the TN3270E-MIB πŸ’… It makes tn3270eBasicGroup and tn3270eSessionGroup mandatory, while tn3270eResMapGroup (client group to resource pool mapping) and tn3270eHiCapacityGroup (high capacity counters) are optional 🌸 A bunch of objects also get relaxed minimum access: read-only is the floor for things like the connectivity check, the TIMING-MARK and NOP settings, the timeout, and all the row status objects, since write access isn't required for those rows πŸ¦‹ The admin status doesn't need to support the stopImmediate transition either πŸ™ˆ And we're left hanging at the units of conformance, which comes next πŸ‘‘

  tn3270eBasicGroup OBJECT-GROUP
      OBJECTS {
          tn3270eSrvrConfInactivityTimeout,
          tn3270eSrvrConfConnectivityChk,
          tn3270eSrvrConfTmNopInactTime,
          tn3270eSrvrConfTmNopInterval,
          tn3270eSrvrFunctionsSupported,
          tn3270eSrvrConfAdminStatus,
          tn3270eSrvrConfOperStatus,
          tn3270eSrvrConfSessionTermState,
          tn3270eSrvrConfSrvrType,
          tn3270eSrvrConfContact,
          tn3270eSrvrConfRowStatus,
          tn3270eSrvrConfLastActTime,
          tn3270eSrvrConfTmTimeout,
          tn3270eSrvrPortRowStatus,
          tn3270eSrvrStatsUpTime,
          tn3270eSrvrStatsMaxTerms,
          tn3270eSrvrStatsInUseTerms,
          tn3270eSrvrStatsSpareTerms,
          tn3270eSrvrStatsMaxPtrs,
          tn3270eSrvrStatsInUsePtrs,
          tn3270eSrvrStatsSparePtrs,
          tn3270eSrvrStatsInConnects,
          tn3270eSrvrStatsConnResrceRejs,
          tn3270eSrvrStatsDisconnects,
          tn3270eSrvrStatsInOctets,
          tn3270eSrvrStatsOutOctets,
          tn3270eSrvrStatsConnErrorRejs,
          tn3270eClientGroupSubnetMask,
          tn3270eClientGroupPfxLength,
          tn3270eClientGroupRowStatus,
          tn3270eSnaMapLocalName,
          tn3270eSnaMapPrimaryLuName,
          tn3270eConfSpinLock
      }
      STATUS  current
      DESCRIPTION
          "This group is mandatory for all hosts supporting the
           TN3270E-MIB."
      ::= { tn3270eGroups 1 }

  tn3270eSessionGroup OBJECT-GROUP
      OBJECTS {
          tn3270eResMapAddrType,
          tn3270eResMapAddress,
          tn3270eResMapPort,
          tn3270eResMapElementType,
          tn3270eResMapSscpSuppliedName,
          tn3270eTcpConnLastActivity,
          tn3270eTcpConnBytesIn,
          tn3270eTcpConnBytesOut,
          tn3270eTcpConnResourceElement,
          tn3270eTcpConnResourceType,
          tn3270eTcpConnDeviceType,
          tn3270eTcpConnFunctions,
          tn3270eTcpConnSrvrConfIndex,
          tn3270eTcpConnActivationTime
        }
      STATUS  current
      DESCRIPTION
          "This group is mandatory for all hosts supporting the
           TN3270E-MIB."
      ::= { tn3270eGroups 2 }

  tn3270eResMapGroup OBJECT-GROUP
      OBJECTS {
          tn3270eResPoolElementType,
          tn3270eResPoolRowStatus,
          tn3270eClientResMapRowStatus,
          tn3270eTcpConnId,
          tn3270eTcpConnClientIdFormat,
          tn3270eTcpConnClientId,
          tn3270eTcpConnTraceData,
          tn3270eTcpConnLogInfo,
          tn3270eTcpConnLuLuBindImage,
          tn3270eTcpConnSnaState,
          tn3270eTcpConnStateLastDiscReason
        }
      STATUS  current
      DESCRIPTION
          "This group is optional for all hosts supporting the
           TN3270E-MIB."
      ::= { tn3270eGroups 3 }

  tn3270eHiCapacityGroup OBJECT-GROUP
      OBJECTS {
          tn3270eSrvrStatsHCInOctets,
          tn3270eSrvrStatsHCOutOctets
        }
      STATUS  current
      DESCRIPTION
           "Support of these objects is REQUIRED when the
           Counter32 versions can potentially wrap too
           frequently.  This group is optional for all other
           hosts supporting the TN3270E-MIB.

           The IF-MIB (RFC 2233) requires that the 64-bit
           versions of its counters be implemented when an
           interface can support rates of around 20 million
           bits per second or greater.  This implies a minimum
           wrap rate of just over 28 minutes.  It is recommended
           that this same guideline be used for determining
           whether an implementation implements these objects.

           This group contains two objects with the syntax
           Counter64.  An implementation that doesn't support
           these objects should return noSuchObject, since
           returning a zero is misleading."

      ::= { tn3270eGroups 4 }

  END

5.0 Security Considerations πŸ”’βœ¨

Okay bestie, security time, and it's SERIOUS. 🫢 Some of the management info in this MIB can be sensitive depending on where you're running it, so in those environments, authentication of received SNMP requests and controlled access to management information SHOULD be employed. πŸ’… The authentication protocol is defined in [12], and the access control protocol is defined in [15]. πŸ”₯

Okay now the scary part πŸ’€. A bunch of objects in this MIB allow write access or let you create rows. If you allow that in a non-secure environment, it can seriously mess with network operations, so it's giving "think very hard first" πŸ™ˆ. Implementers are RECOMMENDED to seriously consider whether set operations or row creation should be allowed without, at a minimum, authentication of request origin. And if you don't have that kind of support, the following objects are RECOMMENDED to be implemented as read-only, no exceptions, periodt πŸ’œ:

  • tn3270eSrvrConfInactivityTimout
  • tn3270eSrvrConfConnectivityChk
  • tn3270eSrvrConfActivityTimeout
  • tn3270eSrvrConfActivityInterval
  • tn3270eSrvrConfAdminStatus
  • tn3270eSrvrConfSessionTermState
  • tn3270eSrvrConfContact
  • tn3270eClientGroupSubnetMask
  • tn3270eResPoolElementType
  • tn3270eSrvrConfRowStatus
  • tn3270eSrvrPortRowStatus
  • tn3270eClientGroupRowStatus
  • tn3270eResPoolRowStatus
  • tn3270eResMapRowStatus

Main character energy, but make it secure. 🌈✨ Almost every table in the MIB uses a first index that identifies one individual TN3270E server. That's SO helpful, because it makes it easy to set up an access control policy where different principals can only touch objects for different servers πŸŽ€. The one exception is the tn3270eTcpConnTable, and you can't do that kind of policy for its entries, tn3270eTcpConTable (as written) lol πŸ™ˆ.

6.0 Intellectual Property πŸ¦‹

Okay so the IETF is NOT taking a side on whether any intellectual property or other rights claimed for this technology are valid or in scope, or whether a license is available, and they're not saying they've tried to find any of those rights either πŸ€·β€β™€οΈ. If you want the details on the IETF's procedures for rights in standards-track and standards-related docs, that's in BCP-11. Copies of rights claims that have been filed for publication, assurances of licenses, or the results of trying to get a general license for implementers or users can all be gotten from the IETF Secretariat πŸ“¬.

The IETF also invites anyone to tell them about copyrights, patents, patent applications, or other proprietary rights that might cover tech needed to practice this standard. Send that info to the IETF Executive Director πŸ’Œ.

7.0 Acknowledgments 🌸

This doc is a product of the TN3270E Working Group, and they're all total queens πŸ‘‘. Big thanks to Randy Presuhn of BMC Software for his really valuable review comments on several versions of the document πŸ«ΆπŸ’–.

8.0 References πŸ“š

  • [1] Harrington D., Presuhn, R. and B. Wijnen, "An Architecture for Describing SNMP Management Frameworks", RFC 2271, January 1998.
  • [2] Rose, M. and K. McCloghrie, "Structure and Identification of Management Information for TCP/IP-based Internets", STD 16, RFC 1155, May 1990
  • [3] Rose, M. and K. McCloghrie, "Concise MIB Definitions", STD 16, RFC 1212, March 1991.
  • [4] Rose, M., "A Convention for Defining Traps for use with the SNMP", RFC 1215, Performance Systems International, March 1991
  • [5] Case, J., McCloghrie, K., Rose, M. and S. Waldbusser, "Structure of Management Information for Version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1902, January 1996.
  • [6] Case, J., McCloghrie, K., Rose, M. and S. Waldbusser, "Textual Conventions for Version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1903, January 1996.
  • [7] Case, J., McCloghrie, K., Rose, M. and S. Waldbusser, "Conformance Statements for Version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1904, January 1996.
  • [8] Case, J., Fedor, M., Schoffstall, M. and J. Davin, "Simple Network Management Protocol", STD 15, RFC 1157, May 1990.
  • [9] Case, J., McCloghrie, K., Rose, M. and S. Waldbusser, "Introduction to Community-based SNMPv2", RFC 1901, January 1996.
  • [10] Case, J., McCloghrie, K., Rose, M. and S. Waldbusser, "Transport Mappings for Version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1906, January 1996.
  • [11] Case, J., Harrington D., Presuhn R. and B. Wijnen, "Message Processing and Dispatching for the Simple Network Management Protocol (SNMP)", RFC 2272, January 1998.
  • [12] Blumenthal, U. and B. Wijnen, "User-based Security Model (USM) for version 3 of the Simple Network Management Protocol (SNMPv3)", RFC 2274, January 1998.
  • [13] Case, J., McCloghrie, K., Rose, M. and S. Waldbusser, "Protocol Operations for Version 2 of the Simple Network Management Protocol (SNMPv2)", RFC 1905, January 1996.
  • [14] Levi, D., Meyer, P. and B. Stewart, "SNMPv3 Applications", RFC 2273, January 1998.
  • [15] Wijnen, B., Presuhn, R. and K. McCloghrie, "View-based Access Control Model (VACM) for the Simple Network Management Protocol (SNMP)", RFC 2275, January 1998.
  • [16] Postel, J. and J. Reynolds, "Telnet Protocol Specification", STD 8, RFC 854, May 1983.
  • [17] Postel, J. and J. Reynolds, "Telnet Timing Mark Option", STD 31, RFC 860, May 1983.
  • [18] Rekhter, J., "Telnet 3270 Regime Option", RFC 1041, January 1988.
  • [19] Kelly, B., "TN3270 Enhancements", RFC 2355, June 1998.
  • [20] McCloghrie, K., "TCP-MIB Definitions", RFC 2012, November 1996.
  • [21] Hovey, R. and S. Bradner, "The Organizations Involved in the IETF Standards Process", BCP 11, RFC 2028, October 1996.
  • [22] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [23] Hinden, R. and S. Deering, "IP Version 6 Addressing Architecture", RFC 2373, July 1998.
  • [24] Krupczak, C. and J. Saperia, "Definitions of System-Level Managed Objects for Applications", RFC 2287, February 1998.

9.0 Authors' Addresses πŸ’Œ

Kenneth D. White, your first author πŸ’–

Kenneth D. White
Dept. BRQA/Bldg. 501/G114
IBM Corporation
P.O.Box 12195
3039 Cornwallis
Research Triangle Park, NC 27709, USA

EMail: kennethw@vnet.ibm.com

And here's Robert Moore, the other author 🧚

Robert Moore
Dept. BRQA/Bldg. 501/G114
IBM Corporation
P.O.Box 12195
3039 Cornwallis
Research Triangle Park, NC 27709, USA

Phone: +1-919-254-4436
EMail: remoore@us.ibm.com

okay bestie, this is the legal bit at the very end πŸ“œβœ¨ and it's giving "you can share this, but don't rename it and pretend you wrote it" πŸ’…

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

So the deal is: anyone can copy this document and hand it to other people, and you can make derivative works that comment on or explain it or help people implement it. You can publish and distribute those too, in whole or in part, with no restrictions at all πŸ¦‹ BUT only if the copyright notice and this paragraph stay on every copy and every derivative work. No ripping them off πŸ™…β€β™€οΈ

The original document itself can't be modified in any way. You can't remove the copyright notice, and you can't scrub the references to the Internet Society or other Internet organizations. The exceptions are when you need it to develop Internet standards, in which case you follow the copyright procedures in the Internet Standards process, or when you need to translate it into a language other than English 🌍

The permissions are perpetual. The Internet Society and its successors or assigns will never take them back 🫢

Now the disclaimer, which is serious even though I'm being cute about it 😭 This document and everything in it is provided "AS IS", and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED. That includes, but isn't limited to, any warranty that using the information won't infringe any rights, and any implied warranty of merchantability or fitness for a particular purpose. So you use it at your own risk, no guarantees πŸ’€

That's the whole thing, we made it to the end of RFC 2561! πŸŒˆπŸŽ€

πŸ“¦ where this page comes from