RFC 2355

TN3270 Enhancements

πŸ“… published June 1998, from ietf

RFC 2355: TN3270 Enhancements πŸŽ€

okay bestie, this one is RFC 2355, and it's called TN3270 Enhancements πŸ’– It's a Standards Track doc from the Network Working Group, written by B. Kelly at Auburn University, dated June 1998 ✨ It obsoletes RFC 1647, so this is the new version that replaces it πŸ’…

Status of This Memo ⭐

This is an Internet standards track protocol for the Internet community, and the authors want discussion and suggestions for improvements 🫢 For the standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited πŸ¦‹

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

Abstract ✨

Okay so this protocol supports 3270 devices way more fully than traditional tn3270 ever did πŸ”₯ It lets you emulate both the terminal and printer members of the 3270 family over Telnet πŸ’œ A Telnet client can ask to be assigned a specific device-name (also called a "LU name" or "network name"). It also adds support for things like the ATTN key, the SYSREQ key, and SNA response handling 🧚

This protocol is negotiated under the TN3270E Telnet Option. It is unrelated to the Telnet 3270 Regime Option defined in RFC 1041 [1] πŸ™ˆ

Table of Contents πŸ“

1.  Introduction ...............................................  2
   1.1  Changes to RFC 1647 ....................................  4
2.  TN3270E OVERVIEW ...........................................  5
3.  COMMAND NAMES AND CODES ....................................  6
4.  COMMAND MEANINGS ...........................................  7
5.  DEFAULT SPECIFICATION ......................................  9
6.  MOTIVATION .................................................  9
7.  TN3270E SUB-NEGOTIATION RULES ..............................  9
   7.1  DEVICE-TYPE Negotiation ................................  9
       7.1.1 Device Pools ...................................... 10
       7.1.2 CONNECT Command ................................... 12
       7.1.3 ASSOCIATE Command ................................. 12
       7.1.4 Accepting a Request ............................... 13
       7.1.5 REJECT Command .................................... 13
   7.2  FUNCTIONS Negotiation .................................. 14
       7.2.1 Commands .......................................... 14
       7.2.2 List of TN3270E Functions ......................... 16
8.  TN3270E DATA MESSAGES ...................................... 16
   8.1  The TN3270E Message Header ............................. 18
       8.1.1 DATA-TYPE Field ................................... 18
       8.1.2 REQUEST-FLAG Field ................................ 19
       8.1.3 RESPONSE-FLAG Field ............................... 19
       8.1.4 SEQ-NUMBER Field .................................. 20
9.  BASIC TN3270E .............................................. 20
   9.1  3270 Mode and NVT Mode ................................. 21
10. DETAILS OF PROCESSING TN3270E FUNCTIONS .................... 22
   10.1 The SCS-CTL-CODES Function ............................. 22
   10.2 The DATA-STREAM-CTL Function ........................... 23
   10.3 The BIND-IMAGE Function ................................ 24
   10.4 The RESPONSES Function ................................. 25
       10.4.1 Response Messages ................................. 26
   10.5 The SYSREQ Function .................................... 28
       10.5.1 Background ........................................ 28
       10.5.2 TN3270E Implementation of SYSREQ .................. 29
11. THE 3270 ATTN KEY .......................................... 30
12. 3270 STRUCTURED FIELDS ..................................... 31
13. IMPLEMENTATION GUIDELINES .................................. 31
   13.1 3270 Data Stream Notes ................................. 31
   13.2 Negotiation of the TN3270E Telnet Option ............... 32
   13.3 A "Keep-alive" Mechanism ............................... 32
   13.4 Examples ............................................... 32
14. SECURITY CONSIDERATIONS .................................... 36
15. REFERENCES ................................................. 36
16. AUTHOR'S NOTE .............................................. 37
17. AUTHOR'S ADDRESS ........................................... 37
18. Full Copyright Statement ................................... 38

1. Introduction ✨

Okay so traditionally, 3270 terminal emulation over Telnet was done with a de facto standard: negotiating three separate Telnet Options, namely Terminal-Type [2], Binary Transmission [3], and End of Record [4] πŸ’… Here's the tea though, there's no RFC that actually specifies this negotiation as a standard 😭 RFC 1041 tried to fix that by defining the 3270 Regime Telnet Option, but very few developers and vendors ever implemented it πŸ’€

This document calls the existing practice of negotiating those three Telnet Options before sending the 3270 data stream "traditional tn3270". Traditional tn3270 is documented in [10] πŸ¦‹

NOTE: Except where otherwise stated, this document does not distinguish between Telnet servers that represent SNA devices and those that represent non-SNA 3270 devices. 🌸

All references in this document to the 3270 data stream, 3270 data stream commands, orders, structured fields and the like rely on [5] 🧚 References to SNA Request and Response Units rely on [6]. References to SNA versus non-SNA operation rely on [7] 🫢

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 πŸ’œ

So traditional tn3270 had some real shortcomings, and the list is kinda iconic πŸ”₯

  • It gave Telnet clients no way to emulate the 328x class of printers πŸ™ˆ
  • There was no way for a Telnet client to ask that its connection be associated with a given 3270 device-name. This matters a lot when a terminal session is being set up, since many host applications act differently depending on the network name of the terminal. For printer emulation it's an absolute necessity, because a huge number of host applications pre-define printer destinations 😭
  • The 3270 ATTN and SYSREQ keys weren't universally supported πŸ’…
  • There was no support for the SNA positive/negative response process. This is super important if printer emulation is going to work properly, but it's also useful for some terminal applications πŸ¦‹ A positive response means the previously received data was processed successfully. A negative response means some sort of error happened while processing the previously received data. That could be because the host application built a 3270 data stream containing an invalid command, or because of a mechanical error on the client side, among other things 🌈
  • There was no way for the client to access the SNA Bind information. The Bind image contains a detailed description of the session between the Telnet server and the host application πŸ“
  • There was no mechanism for the server to figure out whether a client supports 3270 structured fields, or for a client to ask to receive them ✨

1.1. Changes to RFC 1647 🌸

This document replaces RFC 1647. Here's the summary of the changes that went in, bestie πŸ’–

  • Reworded the Introduction to refer to traditional tn3270 in the past tense.
    • Affected sections: 1.
  • Added this section documenting changes to RFC 1647.
    • Affected sections: 1.1
  • Clarified the specification of numeric literals contained in the document.
    • Affected sections: 3. (first paragraph)
  • Extensively revised several sections to:
    1. clarify the motivation behind and use of the ASSOCIATE command
    2. remove restrictive wording regarding the organization and use of server maintained device pools
    3. distinguish between device-names and resource-names in the TN3270E device-type negotiation, and define a maximum length for device-names and resource-names

Affected sections: 4. (DEVICE-TYPE REQUEST command) and 7.1.1 through 7.1.6

  • Corrected the erroneous specification of the format of the function-list sent during TN3270E functions negotiation.
    • Affected sections: 7.2.1 (first paragraph)
  • Added a statement addressing what a client or server should do if an impasse is reached during TN3270E functions negotiation.
    • Affected sections: 7.2.1 (last paragraph)
  • Added a DATA-TYPE of PRINT-EOJ with a value of 0x08 to support the end-of-job indication for printers.
    • Affected sections: 8.1.1, 10.1, 10.2
  • Clarified the description of the SEQ-NUMBER Field to state that:
    1. the field should be sent in network byte order (big endian)
    2. either byte that contains a 0xff must be doubled to 0xffff before sending, and stripped back to 0xff after receipt.

Affected sections: 8.1.4

  • Defined the format and maximum length of the Bind image.
    • Affected sections: 10.3 (fourth paragraph)
  • Clarified the misleading wording regarding allowable DATA-TYPEs when BIND-IMAGE has been negotiated and a BIND has been sent.
    • Affected sections: 10.3 (last paragraph)
  • Clarified the use of the SEQ-NUMBER field in regards to when it should be reset to zero.
    • Affected sections: 10.4 (last paragraph)
  • Clarified the format of the data when the DATA-TYPE field is SSCP-LU-DATA.
    • Affected sections: 10.5.2 (fourth paragraph)
  • Reworded the Security section to refer to Kerberos.
    • Affected sections: 14.

2. TN3270E Overview ✨

okay so to fix all these problems, this doc proposes a brand new Telnet Option called TN3270E πŸ¦‹ Telnet clients and servers are totally free to negotiate it or not πŸ’… If either side doesn't support TN3270E, you just use traditional tn3270. Otherwise, they do a sub-negotiation to figure out which subset of TN3270E they'll actually use on the session. It's anticipated that a client or server that can do both types of 3270 emulation would try TN3270E first, and only negotiate traditional tn3270 if the other side refuses TN3270E. ngl that's very polite-but-persistent energy ✨

Once a client and server have agreed to use TN3270E, they can start negotiating the TN3270E suboptions πŸŽ€ The two big pieces are:

  • a device-type negotiation that's kinda like the existing Telnet Terminal-Type Option, but a bit more complicated 🌸
  • negotiating a set of supported 3270 functions, like printer data stream type (3270 data stream or SNA Character Stream), positive/negative response exchanges, device status information, and passing BIND information from server to client πŸ’œ

Successful negotiation of these two suboptions is the signal that 3270 data stream transmission can begin πŸ”₯ Also, to support several of the new functions, each data message has to be prefixed by a header 🧚 That header carries flags and indicators for things like positive and negative responses, plus what type of data follows it (3270 data stream, SNA Character Stream, or device status information) 🫢

3. Command Names and Codes 🌈

Please note that all numeric literals in this document specify decimal values, unless they are preceded by "0x", in which case a hexadecimal value is represented πŸ”’

    TN3270E            40
      ASSOCIATE          00
      CONNECT            01
      DEVICE-TYPE        02
      FUNCTIONS          03
      IS                 04
      REASON             05
      REJECT             06
      REQUEST            07
      SEND               08

    Reason-codes
      CONN-PARTNER       00
      DEVICE-IN-USE      01
      INV-ASSOCIATE      02
      INV-NAME           03
      INV-DEVICE-TYPE    04
      TYPE-NAME-ERROR    05
      UNKNOWN-ERROR      06
      UNSUPPORTED-REQ    07

    Function Names
      BIND-IMAGE         00
      DATA-STREAM-CTL    01
      RESPONSES          02
      SCS-CTL-CODES      03
      SYSREQ             04

4. Command Meanings πŸ’…

Refer to the Telnet Protocol Specification [8] for the meaning of IAC, DO, WILL, etc. πŸ“–

IAC WILL TN3270E 🌸

The sender of this command is willing to send TN3270E information in subsequent sub-negotiations.

IAC WON'T TN3270E πŸ™ˆ

The sender of this command refuses to send TN3270E information.

IAC DO TN3270E 🫢

The sender of this command is willing to receive TN3270E information in subsequent sub-negotiations.

IAC DON'T TN3270E πŸ’€

The sender of this command refuses to receive TN3270E information.

Note that while they are not explicitly negotiated, the equivalent of the Telnet Binary Transmission Option [3] and the Telnet End of Record Option [4] is implied in the negotiation of the TN3270E Option. That is, a party to the negotiation that agrees to support TN3270E is automatically required to support bi-directional binary and EOR transmissions. so it's like, built in, no extra ask πŸŽ€

IAC SB TN3270E SEND DEVICE-TYPE IAC SE πŸ“£

IAC SB TN3270E SEND DEVICE-TYPE IAC SE

Only the server may send this command. It's used to request that the client transmit a device-type and, optionally, device-name information.

IAC SB TN3270E DEVICE-TYPE REQUEST <device-type> [ [CONNECT <resource-name>] | [ASSOCIATE <device-name>] ] IAC SE πŸ¦‹

IAC SB TN3270E DEVICE-TYPE REQUEST <device-type>
    [ [CONNECT <resource-name>] | [ASSOCIATE <device-name>] ] IAC SE

Only the client may send this command. It's used in response to the server's SEND DEVICE-TYPE command, and also to suggest another device-type after the server has sent a DEVICE-TYPE REJECT command (see below). This command requests emulation of a specific 3270 device type and model. The REQUEST command may optionally include either the CONNECT or the ASSOCIATE command (but not both). If present, CONNECT must be followed by <resource-name> and ASSOCIATE must be followed by <device-name>. (See the section entitled "DEVICE-TYPE Negotiation" for more detailed information.) 🧚

IAC SB TN3270E DEVICE-TYPE IS <device-type> CONNECT <device-name> IAC SE ✨

IAC SB TN3270E DEVICE-TYPE IS <device-type> CONNECT
    <device-name> IAC SE

Only the server may send this command. It's used to accept a client's DEVICE-TYPE REQUEST command and to return the server-defined device-name. πŸ”₯

IAC SB TN3270E DEVICE-TYPE REJECT REASON <reason-code> IAC SE 🚫

IAC SB TN3270E DEVICE-TYPE REJECT REASON <reason-code> IAC SE

Only the server may send this command. It's used to reject a client's DEVICE-TYPE REQUEST command. πŸ’œ

IAC SB TN3270E FUNCTIONS REQUEST <function-list> IAC SE πŸ‘‘

IAC SB TN3270E FUNCTIONS REQUEST <function-list> IAC SE

Either side may send this command. It's used to suggest a set of 3270 functions that will be supported on this session. It's also sent as an implicit rejection of a previous FUNCTIONS REQUEST command sent by the other side (see the section entitled "FUNCTIONS Negotiation" for more information). Note that when used to reject a FUNCTIONS REQUEST command, the function-list must not be identical to that received in the previous REQUEST command. πŸ™…β€β™€οΈ

IAC SB TN3270E FUNCTIONS IS <function-list> IAC SE 🌟

IAC SB TN3270E FUNCTIONS IS <function-list> IAC SE

Either side may send this command. It's sent as a response to a FUNCTIONS REQUEST command and implies acceptance of the set of functions sent in the REQUEST command. Note that the list of functions in the FUNCTIONS IS command must match the list that was received in the previous FUNCTIONS REQUEST command. πŸ“

5. Default Specification πŸŽ€

WON'T TN3270E

DON'T TN3270E

i.e., TN3270E will not be used. πŸ™ƒ

6. Motivation πŸ’–

See the section entitled "Introduction".

7. TN3270E Sub-negotiation Rules 🌸

Once it has been agreed that TN3270E will be supported, the first sub-negotiation must concern the DEVICE-TYPE (and possibly device-name) information. Only after that has been successfully negotiated can the client and server exchange FUNCTIONS information. Only after both DEVICE-TYPE and FUNCTIONS have been successfully negotiated can 3270 data stream transmission occur. It's giving strict order, bestie, no skipping ahead πŸ’…

7.1 DEVICE-TYPE Negotiation πŸ¦‹

Device-type names are NVT ASCII strings, all upper case.

Device-type (and device-name) negotiation begins when the server transmits the DEVICE-TYPE SEND command to the client. The client responds with the DEVICE-TYPE REQUEST command, which must include a device-type and may include a resource-name or device-name request. 🧚

Valid device-types are:

  erminals: IBM-3278-2  IBM-3278-2-E  (24 row x 80 col display)
            IBM-3278-3  IBM-3278-3-E  (32 row x 80 col display)
            IBM-3278-4  IBM-3278-4-E  (43 row x 80 col display)
            IBM-3278-5  IBM-3278-5-E  (27 row x 132 col display)
            IBM-DYNAMIC            (no pre-defined display size)

  printers: IBM-3287-1

Note that the use of '3278' and '3287' is NOT intended to exclude any particular device capabilities. They're used here only because they're commonly known designations for a terminal and a printer member of the 3270 family of devices. The intention is to simplify the device-type negotiation (compared to traditional tn3270) by minimizing the number of possible device-types, and by breaking the association of a specific piece of IBM hardware with a related set of data stream capabilities. For example, negotiation of device-type IBM-3278-2-E does NOT in and of itself preclude the use of any of the functions associated with a physical 3279 model S2B. A client's ability to support the more advanced functions of the 3270 data stream will be indicated not by negotiation of an IBM device type and model number, but rather by the combination of Read Partition Query and Query Reply. πŸ”βœ¨

All of the terminal device-types support a "primary" display size of 24 rows by 80 columns. The "-3", "-4" and "-5" types each support an "alternate" display size as noted in the above list. The IBM-DYNAMIC device-type implies no pre-defined alternate display size. This value will be passed from the client to host applications as part of the Query Reply structured field, and it can represent any display size the client and the host application can support. πŸ“πŸ’œ

Terminal device-types with the "-E" suffix should only be negotiated by clients that are willing to support some subset of the 3270 "extended data stream". This usually includes, at a minimum, support for extended colors and highlighting, but may also include a number of other functions, such as graphics capability, alternate character sets, and partitions. 🌈

Clients that negotiate a terminal device-type with the "-E" suffix or the DYNAMIC type, as well as those that negotiate a printer device-type, must be able to accept and respond to a Read Partition Query command (see the section entitled "3270 Structured Fields"). This allows the client to indicate to host applications which subsets of the 3270 extended data stream the client is willing to support. 🫢

In a VTAM/SNA environment, negotiation of IBM-DYNAMIC as the device-type should result in a Bind in which the Presentation Services Usage screen field (the eleventh byte in the logmode's PSERVIC field) is set to 0x03, indicating that the alternate screen size will be determined by the Query Reply (Usable Area). πŸŽ€πŸ‘‘

7.1.1 Device Pools ✨

Okay bestie, before we get into CONNECT and ASSOCIATE, we need to talk about how the server organizes its terminal and printer device pools πŸŠβ€β™€οΈ and picks the device-names it hands out to session requests. A few terms first πŸ“š

"device-name", "LU name" and "network name" are basically interchangeable here. They all mean one specific terminal or printer device πŸ’–

"resource-name" is the less specific one. It might be a device-name, but it could also be the name of a whole pool of printer or terminal devices. A named pool like that could group devices with similar operational or administrative vibes πŸ¦‹ This doc doesn't care how a server uses resource-names, as long as the server can take the resource-name the client sent and turn it into a device-name to assign to the session. But servers must avoid ambiguity πŸ™…β€β™€οΈ so they must not allow a device-name to be defined with the same name as a pool of devices. Iykyk πŸ’€

Device-names and resource-names are NVT ASCII strings where upper and lower case are considered equivalent. Their length should not exceed 8 bytes πŸŽ€

A "generic session request" is one that includes neither the CONNECT nor the ASSOCIATE command. A "specific session request" is one that includes either CONNECT or ASSOCIATE 🌸

If a TN3270E server wants to support traditional tn3270 clients, it must maintain a set of terminal device-names that can be used to satisfy those clients' requests for terminal sessions. That same pool could also be used to satisfy generic terminal requests from TN3270E clients πŸ’œ

The server can also maintain as many other pools of device-names as it likes 🌈 For example, there could be a pool of terminal device-names reserved for one department in the organization, or a pool of terminal device-names that have access to certain applications on the host πŸ“

For any of these terminal pools, the TN3270E server may also have defined a "partner" or "paired" printer device for each terminal in the pool. There should be a unique, one-to-one mapping between a terminal and its printer 🫢 The whole point is to support host applications that send printed output to a printer whose device-name is determined by the device-name of the terminal that started the print request. These partner printers can only be assigned to specific printer session requests that use the ASSOCIATE command (see below) πŸ–¨οΈ

The server may also maintain one or more pools of printer device-names that aren't associated with any terminal 🧚 These printers can only be assigned to specific printer session requests that use the CONNECT command (see below). This is for host applications that send printed output to a printer whose device-name is determined by something other than the terminal that started the print request. For example, the userid of the person signed on to a terminal might decide the print destination πŸ‘‘ It's also possible to maintain a pool of printer device-names to satisfy generic printer requests, meaning ones that specify neither CONNECT nor ASSOCIATE πŸ’…

7.1.2 CONNECT Command πŸ”Œ

CONNECT can be used by the client in two ways. If the resource-name it specifies is a device-name, the client is requesting that specific device-name. If the specified resource-name is not a device-name, the client is requesting any one of the device-names associated with that resource-name πŸ¦‹

In either case, the resource indicated by the specified resource-name must not conflict with the device-type. For example, if the client requests DEVICE-TYPE IBM-3287-1 (a printer) and specifies CONNECT T1000001, but T1000001 is a device-name defined at the host as a terminal, then the server must deny the request πŸ™…β€β™€οΈ Also, if the requested resource-name is a device-name that is already associated with some other Telnet session, or if it isn't defined to the server at all, the server must deny the request 😭

7.1.3 ASSOCIATE Command πŸŽ€

ASSOCIATE can be used by the client only when it requests a DEVICE-TYPE that represents a printer. The specified device-name must be that of a terminal that the server returned in a previous DEVICE-TYPE IS <device-type> CONNECT <device-name> command 🌷

The ASSOCIATE command requests that this session be assigned the device-name of the printer that is paired with the terminal named in the request πŸ–¨οΈ If the device-type doesn't represent a printer, or if the device-name isn't that of a terminal, the server must deny the request. And if the server hasn't defined a partner printer for the specified terminal, it must deny the request too πŸ’€

Here's how it's meant to flow ✨ A client first connects and requests a terminal from one of the terminal pools. Then it uses the terminal device-name the server returned (see "Accepting a Request", section 7.1.4 below) in a second session request, this time asking for the printer paired with the terminal session it just set up. This lets clients associate a printer session with a terminal, without needing to know a printer device-name ahead of time 🧚

7.1.4 Accepting a Request πŸ’–

The server must either accept the client's request or deny it as a whole. It can't, for example, accept the DEVICE-TYPE request but deny the CONNECT portion πŸ™…β€β™€οΈ

If the server wants to accept the request, it sends back the DEVICE-TYPE IS command confirming the requested device-type, and the CONNECT command specifying the device-name of the terminal or printer assigned to this session πŸ₯°

Normally, the client should accept any DEVICE-TYPE IS <device-type> CONNECT <device-name> sent by the server. The exception is if the client must (for example, to satisfy local-site policy) be connected to a specific LU name, and is presented with a device-name that doesn't match the one it requested. This could happen, for example, if the client requested what it thought was a device-name, but the server had defined that name as a pool of devices. In this case, the client should reject the DEVICE-TYPE IS command by terminating TN3270E negotiations 😱

7.1.5 REJECT Command 🚫

If the server wants to deny the request, it sends back the DEVICE-TYPE REJECT command with one of the following reason-codes πŸ’…

Reason code name         Explanation
----------------         -----------------------------------
INV-DEVICE-TYPE          The server does not support the
                         requested device-type.

INV-NAME                 The resource-name or device-name
                         specified in the CONNECT or ASSOCIATE
                         command is not known to the server.

DEVICE-IN-USE            The requested device-name is
                         already associated with another
                         session.

TYPE-NAME-ERROR          The requested device-name or
                         resource-name is incompatible
                         with the requested device-type
                         (such as terminal/printer mismatch).

UNSUPPORTED-REQ          The server is unable to satisfy
                         the type of request sent by the
                         client; e.g., a specific terminal
                         or printer was requested but the
                         server does not have any such pools of
                         device-names defined to it, or the
                         ASSOCIATE command was used but no
                         partner printers are defined to the
                         server.

INV-ASSOCIATE            The client used the ASSOCIATE
                         command and either the device-type
                         is not a printer or the device-name
                         is not a terminal.

CONN-PARTNER             The client used the CONNECT command
                         to request a specific printer but
                         the device-name requested is the
                         partner to some terminal.

UNKNOWN-ERROR            Any other error in device type or
                         name processing has occurred.

Negotiating a device-type and device-name that both client and server are happy with might take several rounds of DEVICE-TYPE REQUEST and DEVICE-TYPE REJECT commands πŸ”„ The client must use the reason-code the server gives in any DEVICE-TYPE REJECT command to keep the negotiation as short as possible πŸƒβ€β™€οΈ For example, if the client first asks for a specific terminal device-name via CONNECT, and the server rejects it with a reason-code of UNSUPPORTED-REQ, the client must not make any more specific terminal requests during the negotiation πŸ™ˆ And if either side wants to "bail out" at any point, it can simply send a WON'T (or DON'T) TN3270E command to the other side. At that point, both sides are free to negotiate other Telnet options (including traditional tn3270) πŸ¦‹

7.2 FUNCTIONS Negotiation 🌈

Once DEVICE-TYPE negotiation has successfully completed (i.e, when the client receives a DEVICE-TYPE IS command that it finds acceptable), the client must start FUNCTIONS negotiation by sending the FUNCTIONS REQUEST command to the server πŸŽ‰ After that initial REQUEST command, both sides are free to send FUNCTIONS REQUEST and FUNCTIONS IS commands as needed ✨

7.2.1 Commands πŸ“¨

Okay so the FUNCTIONS REQUEST command is basically the sender going "hey, here's the list of TN3270E functions I'd looove to have on this session πŸ’…." Anything NOT on the list counts as unsupported, no cap. The list ends with the IAC code right before the SE command, and the functions can show up in any order πŸ¦‹

When a FUNCTIONS REQUEST lands, the recipient has two options:

  • Say yes: it agrees to support every function on the list AND promises not to send any data for functions that aren't on it. To make it official, it sends a FUNCTIONS IS command with the function-list exactly as it came in. And just like that, FUNCTIONS negotiation is successfully done ✨
  • Say no: it sends back its own FUNCTIONS REQUEST, but the function-list has to be different. Reordering doesn't count, so at least one function has to be added or removed πŸ™ˆ

Now the loop thing, and this is important bestie πŸ” To avoid endlessly bouncing back and forth, both parties must not add to the function-list they receive any function that they previously added and the other side removed.

The back-and-forth keeps going until one side gets a function-list it's willing to live with. That side uses FUNCTIONS IS to accept, and once the other side receives it, all the necessary negotiation is complete. That's the green light for 3270 data stream transmission to begin 🚦

Also, the function-list that ends up agreed on can be null. That's called "basic TN3270E" πŸ“ Check out the section called "Basic TN3270E" if you want the deets.

If things reach an impasse during FUNCTIONS negotiation (for example, a client asked for and got a DEVICE-TYPE that represents a printer, but then refuses both SCS-CTL-CODES and DATA-STREAM-CTL), the "offended" party should end the negotiation by sending IAC DON'T (or WON'T) TN3270E. Drama, but make it protocol πŸ’€

7.2.2 List of TN3270E Functions 🧚

Here's the quick tour of the 3270 functions that can get negotiated into the function-list:

Function Name       Description
-------------       -----------
SCS-CTL-CODES       (Printer sessions only).  Allows the use
                    of the SNA Character Stream (SCS) and SCS
                    control codes on the session.  SCS is
                    used with LU type 1 SNA sessions.

DATA-STREAM-CTL     (Printer sessions only).  Allows the use
                    of the standard 3270 data stream.  This
                    corresponds to LU type 3 SNA sessions.

RESPONSES           Provides support for positive and
                    negative response handling.  Allows the
                    server to reflect to the client any and
                    all definite, exception, and no response
                    requests sent by the host application.

BIND-IMAGE          Allows the server to send the SNA Bind
                    image and Unbind notification to the
                    client.

SYSREQ              Allows the client and server to emulate
                    some (or all, depending on the server) of
                    the functions of the SYSREQ key in an SNA
                    environment.

For the full tea on what each of these actually does, go read the section called "Details of Processing TN3270E Functions" πŸ“–

And if you get an unrecognized function code during functions negotiation, the recipient should just remove that code from the list and keep on with normal negotiation. No drama, just vibes 🫢

8. TN3270E Data Messages πŸ’Œ

3270 device communications are generally understood to be block oriented. Basically, each partner buffers data until a whole "message" has been built, and then it gets sent to the other side πŸ“¦ The "outbound message" (host to device) is a 3270 command plus a series of buffer orders, buffer addresses, and data. The "inbound message" only has buffer orders, addresses, and data. The end of a message is the last byte transmitted (this discussion ignores SNA chaining, so don't @ me πŸ™ˆ). The Telnet EOR command is used to mark off these natural blocks of 3270 data inside the Telnet data stream.

In TN3270E, every 3270 message has to be prefixed with a TN3270E header, which is five bytes long. Its format is defined below (see the section called "The TN3270E Message Header"). So a "data message" in TN3270E looks like this:

<TN3270E Header><data><IAC EOR>

For certain message types there might be no data portion at all. In that case, the TN3270E data message is just:

<TN3270E Header><IAC EOR>

Now, if either side wants to send the decimal value 255 and have it treated as data, it must "double" that byte. So one 255 gets read by the other side as an IAC, but two 255 bytes in a row get read as one data byte with the value 255. Double it up, babe πŸ‘‘

Telnet commands (other than IAC IAC) are strongly recommended to be sent between TN3270E data messages, with no header and no trailing IAC EOR. If a TN3270E data message containing IAC IP (which means 3270 Attention) or IAC AO (which means SYSREQ) comes in, the receiver should hold off on processing that command until the 3270 data has been processed. Check the right sections for the full Attention and SYSREQ tea β˜• If a TN3270E data message contains any other IAC-command sequence (other than IAC IAC), it's up to the implementation when that sequence gets processed, but it must be processed. The receiver can handle it right away, which acts as if it arrived before the current TN3270E data message, or it can wait until after the current message is done. This is the ambiguity part πŸŒ€ That's exactly why Telnet commands inside a TN3270E data message (between the header and the trailing IAC EOR) are not recommended, and neither clients nor servers should send them.

8.1. The TN3270E Message Header πŸŽ€

As we said earlier, every TN3270E data message must be prefixed by a header. It's five bytes, and it looks like this:

-----------------------------------------------------------
| DATA-TYPE | REQUEST-FLAG | RESPONSE-FLAG |  SEQ-NUMBER  |
-----------------------------------------------------------
   1 byte        1 byte         1 byte         2 bytes

8.1.1 DATA-TYPE Field πŸ¦‹

The DATA-TYPE field tells the receiver how to read the data portion of the message. Here are the possible values:

Data-type Name   Code                Meaning
--------------   ----   ---------------------------------
3270-DATA        0x00   The data portion of the message
                        contains only the 3270 data stream.

SCS-DATA         0x01   The data portion of the message
                        contains SNA Character Stream data.

RESPONSE         0x02   The data portion of the message
                        constitutes device-status information
                        and the RESPONSE-FLAG field indicates
                        whether this is a positive or negative
                        response (see below).

BIND-IMAGE       0x03   The data portion of the message is
                        the SNA bind image from the session
                        established between the server and the
                        host application.

UNBIND           0x04   The data portion of the message is
                        an Unbind reason code.

NVT-DATA         0x05   The data portion of the message is to
                        be interpreted as NVT data.

REQUEST          0x06   There is no data portion present in
                        the message.  Only the REQUEST-FLAG
                        field has any meaning.

SSCP-LU-DATA     0x07   The data portion of the message is
                        data from the SSCP-LU session.

PRINT-EOJ        0x08   There is no data portion present in
                        the message.  This value can be sent
                        only by the server, and only on a
                        printer session.

8.1.2 REQUEST-FLAG Field 🌸

The REQUEST-FLAG field only means something when DATA-TYPE is set to REQUEST. Otherwise, the receiver must ignore REQUEST-FLAG, and the sender should set it to 0x00. Here are the possible values:

Request-Flag Name   Code                Meaning
-----------------   ----   ---------------------------------
ERR-COND-CLEARED    0x00   The client sends this to the server
                           when some previously encountered
                           printer error condition has been
                           cleared.  (See the section entitled
                           "The RESPONSES Function" below.)

8.1.3 RESPONSE-FLAG Field πŸ’…

okay so the RESPONSE-FLAG field is kinda picky πŸ™ˆ it only means something for certain DATA-TYPE values. for 3270-DATA and SCS-DATA, it tells you whether the sender is expecting a reply back. the possible values are:

Response-Flag Name  Code                Meaning
------------------  ----   ---------------------------------
NO-RESPONSE         0x00   The sender does not expect the
                           receiver to respond either
                           positively or negatively to this
                           message.  The receiver MUST
                           therefore not send any response
                           to this data-message.

ERROR-RESPONSE      0x01   The sender only expects the
                           receiver to respond to this message
                           if some type of error occurred, in
                           which case a negative response MUST
                           be sent by the receiver.

ALWAYS-RESPONSE     0x02   The sender expects the receiver to
                           respond negatively if an error
                           occurs, or positively if no errors
                           occur.  One or the other MUST
                           always be sent by the receiver.

so NO-RESPONSE means radio silence 🀐 the receiver MUST NOT send anything back. ERROR-RESPONSE means "only speak up if something went wrong," and ALWAYS-RESPONSE means you always get a yes or a no. no ghosting allowed πŸ’€

For a DATA-TYPE field value of RESPONSE, the RESPONSE-FLAG is the actual reply to an earlier data message. that earlier message MUST by definition have had a DATA-TYPE of either 3270-DATA or SCS-DATA and a RESPONSE-FLAG value of either ERROR-RESPONSE or ALWAYS-RESPONSE. ✨ in this case the possible values are:

Response-Flag Name  Code                Meaning
------------------  ----   ---------------------------------
POSITIVE-RESPONSE   0x00   The previous message was received
                           and executed successfully with
                           no errors.

NEGATIVE-RESPONSE   0x01   The previous message was received
                           but an error(s) occurred while
                           processing it.

Accompanying status information will be found in the data portion of the message. πŸŽ€

For any other values of the DATA-TYPE field, the RESPONSE-FLAG field MUST be ignored by the receiver and SHOULD be set to 0x00 by the sender. so if it's not one of those special DATA-TYPEs, just let it be πŸ¦‹

8.1.4 SEQ-NUMBER Field 🧚

the SEQ-NUMBER field only shows up when the RESPONSES function has been agreed to. it's a 2 byte binary number, and its whole job is to match up positive and negative responses with the data messages they were meant for, like a little name tag 🏷️ this field MUST be sent in network byte order ("big endian"). and if either byte is a 0xff, it SHOULD be doubled to 0xffff before sending, then stripped back down to 0xff when it's received. this is standard IAC escaping, bestie, nothing new πŸ’–

If you want the full story on how this field gets used, check the section called "The RESPONSES Function." When the RESPONSES function is not agreed to, this field SHOULD always be set to 0x0000 by the sender and ignored by the receiver. 🌸


9. Basic TN3270E ✨

okay so as we said earlier, whether each TN3270E function is allowed on a session gets negotiated when the connection is set up. it's possible that none of the functions get agreed to, which means the function-list in the FUNCTIONS REQUEST and FUNCTIONS IS commands is null. this mode is called "basic TN3270E" πŸ“

Here's the thing: since neither the SCS-CTL-CODES function nor the DATA-STREAM-CTL function is agreed to, basic TN3270E is only for terminal sessions. no printers allowed πŸ–¨οΈπŸš«

Basic TN3270E requires support for only the following TN3270E header values:

          Header field         Value
          ------------         -----
           DATA-TYPE          3270-DATA
           DATA-TYPE          NVT-DATA

The REQUEST-FLAG, RESPONSE-FLAG and SEQ-NUMBER fields are not used in basic TN3270E. honestly, that's a very chill, very minimal vibe ☁️

9.1 3270 Mode and NVT Mode πŸ¦‹

okay this one's giving "two modes, one connection." at any given time, a TN3270E connection is either in "3270 mode" or "NVT mode." in 3270 mode, each party can send data messages with DATA-TYPE set to 3270-DATA. sending NVT-DATA in that mode is a request to switch modes. in NVT mode, it's flipped: each party can send NVT-DATA, and sending 3270-DATA is the request to switch. the connection starts out in 3270 mode once TN3270E operation is successfully negotiated. 🌈

when a party gets a message with a DATA-TYPE that doesn't match the mode it's in, the connection's mode switches. and yes, switching modes makes the client do the equivalent of a 3270 Erase/Reset operation, as described in [5], using the default partition (screen) size. it's like a fresh start 🧹 the server can't assume the client keeps any attributes from the previous environment across a mode switch, so don't get attached πŸ™ƒ

Note that even when sending NVT-DATA, each side SHOULD buffer data until an entire message is built. for the client, that usually means until the user hits Enter ⌨️ at that point, a complete TN3270E data message SHOULD be built to carry the NVT data.

Typically, NVT data is how a server chats with the user on the client side. it lets the server use a simple NVT data stream instead of needing a full 3270 data stream. for example, a server might show a list of 3270 applications it can connect the client to. the server would use NVT data to display that list and read the user's pick. then it connects to the chosen application and the 3270 data exchange begins between that application and the client. πŸ’…


10. Details of Processing TN3270E Functions πŸ‘‘

okay, important bit: if both parties agree to a function in the FUNCTIONS REQUEST function-list, that also means each party agrees to support a related set of TN3270E header values. it also means they're willing to follow the rules for processing data messages for that function. so no skipping the rules, babe 🌈

Either party that fails to accept header values tied to an agreed function or to basic TN3270E, or that tries to use header values tied to a function that's not part of basic TN3270E and wasn't agreed to, will be considered non-conforming and in violation of the protocol. πŸ’€ yikes. the sections below spell out the header values and processing rules for each function.

10.1 The SCS-CTL-CODES Function πŸ–¨οΈ

This function can only be supported on a 3270 printer session. πŸŽ€

Agreeing to support this function requires that the party support these TN3270E header values:

          Header field         Value
          ------------         -----
           DATA-TYPE          SCS-DATA
           DATA-TYPE          PRINT-EOJ

A client representing a printer device uses this function to say it's willing to accept a data stream that includes SCS control codes. for the purposes of NVT mode versus 3270 mode, SCS-DATA MUST be treated exactly like 3270-DATA (so it can switch the connection from NVT mode to 3270 mode). ✨

When a printer device-type has been negotiated, either the SCS-CTL-CODES function or the DATA-STREAM-CTL function, or both, MUST be negotiated. this is what lets the server know when it should and should not accept a session with a host application for the client 🧠 if only SCS-CTL-CODES is agreed to, the server won't set up sessions with host applications that would send 3270 data stream control. if both SCS-CTL-CODES and DATA-STREAM-CTL are agreed to, the server will set up sessions with both kinds: the ones that send SCS control codes and the ones that send 3270 orders.

The server SHOULD send a TN3270E message with DATA-TYPE set to PRINT-EOJ at the end of each print job. that tells the client it can now take whatever action makes sense for its environment (e.g., close a disk or spool file, etc.) πŸ“„ the server MAY have multiple criteria for deciding when it SHOULD send a PRINT-EOJ, like receiving SNA End Bracket from the host application, or a pre-defined timeout running out ⏰

10.2 The DATA-STREAM-CTL Function πŸ§šβ€β™€οΈ

This function can only be supported on a 3270 printer session. πŸŽ€

Agreeing to support this function requires that the party support these TN3270E header values:

          Header field         Value
          ------------         -----
           DATA-TYPE          3270-DATA
           DATA-TYPE          PRINT-EOJ

A client representing a printer device uses this function to say it's willing to accept a data stream that includes 3270 orders and attributes. πŸ’œ

When a printer device-type has been negotiated, either the SCS-CTL-CODES function or the DATA-STREAM-CTL function, or both, MUST be negotiated. this lets the server know when it SHOULD and SHOULD NOT accept a session with a host application on the client's behalf 🫢 if only DATA-STREAM-CTL is agreed to, the server won't set up sessions with host applications that would send SCS control codes in a data stream. if both SCS-CTL-CODES and DATA-STREAM-CTL are agreed to, the server will set up sessions with both the host apps that send SCS control codes and the ones that send 3270 orders.

The server SHOULD send a TN3270E message with DATA-TYPE set to PRINT-EOJ at the end of each print job, so the client knows it may now take whatever action is appropriate for its environment (e.g., close a disk or spool file, etc.) 🌸 the server MAY have multiple criteria for deciding when it SHOULD send a PRINT-EOJ, like receiving SNA End Bracket from the host application, or a pre-defined timeout expiring πŸ“

10.3. The BIND-IMAGE Function πŸŽ€

okay bestie, this function can only be supported when the TN3270E server is representing SNA terminals and printers πŸ–₯️✨

agreeing to support it means you have to support these TN3270E header values πŸ’…

             Header field         Value
             ------------         -----
              DATA-TYPE          BIND-IMAGE
              DATA-TYPE          UNBIND
              DATA-TYPE          SSCP-LU-DATA

when BIND-IMAGE is in effect, the server must tell the client when an SNA session with a host application has been set up, and when it's been ended. it uses the DATA-TYPE values BIND-IMAGE and UNBIND to get that info across πŸ¦‹

when the server sets up an SNA session on behalf of a client, it gets a Bind RU from the host application. it also gets a Start Data Traffic RU 🌸 once the server has answered both of those positively, it must send the client a data message with DATA-TYPE set to BIND-IMAGE to say the session is there. the data portion of that message has to hold the bind image exactly as it came in the Bind RU the server accepted for the client. the format and maximum length of that bind image are defined in [6] πŸ“œ

when an SNA session between the server and a host application ends, the server must send the client a data message with DATA-TYPE set to UNBIND. if the server heard about the end through an SNA Unbind RU, it should put the Unbind reason code in the data portion of the message it sends to the client. if the server itself asked for the session to end (for example, during SYSREQ key processing), it should set the data portion of the UNBIND message to 0x01, which means "normal end of session" πŸ“

BIND-IMAGE also changes which DATA-TYPE values are allowed, a little bit, compared to what's in the section called "Basic TN3270E" πŸ‘‘ when BIND-IMAGE is in effect, data messages with DATA-TYPE set to 3270-DATA or SCS-DATA are not allowed before the client gets its first BIND-IMAGE. only SSCP-LU-DATA or NVT-DATA can carry user-oriented data during that time. the same rule applies to data messages sent after an UNBIND and before the client gets another BIND-IMAGE πŸ™ˆ once the client has a BIND-IMAGE data message, the allowed DATA-TYPE values now include SSCP-LU-DATA plus 3270-DATA and/or SCS-DATA. which ones depends on whether a terminal or printer device-type was negotiated, and whether a printer client agreed to DATA-STREAM-CTL or SCS-CTL-CODES, or both ⭐ (check out "The SYSREQ Function" section for more on the SSCP-LU session in an SNA environment 🫢)

10.4. The RESPONSES Function πŸ’œ

this one can be supported for both terminal and printer sessions, whether the server is connected to an SNA or a non-SNA host ✨

to agree to support it, you have to support these TN3270E header values:

             Header field         Value
             ------------         -----
              DATA-TYPE          RESPONSE
              DATA-TYPE          REQUEST
              RESPONSE-FLAG      -all values-
              REQUEST-FLAG       ERR-COND-CLEARED
              SEQ-NUMBER         binary values from 0-32767

whenever a data message goes out with DATA-TYPE set to SCS-DATA or 3270-DATA, the sender must set the RESPONSE-FLAG field to NO-RESPONSE, ERROR-RESPONSE, or ALWAYS-RESPONSE πŸ’… the client side is expected to normally set RESPONSE-FLAG to NO-RESPONSE. if the server represents an SNA device, it should set RESPONSE-FLAG to match the response setting in the RH of the RU that made this data message. so a Definite Response becomes ALWAYS-RESPONSE, an Exception Response becomes ERROR-RESPONSE, and No Response gets NO-RESPONSE πŸ”₯ a non-SNA server should set RESPONSE-FLAG to ERROR-RESPONSE.

the sender also has to keep a count of the messages with DATA-TYPE 3270-DATA or SCS-DATA that it sends on a given TN3270E session 🧚 this counter should start at zero for the first one and go up by one for each message after that. it's totally separate from any SNA sequence numbers, and it should not be reset to zero because of a Bind or Unbind. if the counter hits the maximum of 32767, it should restart at zero. the sender must put this value in the SEQ-NUMBER field of the TN3270E header before sending the message. and the SEQ-NUMBER field must be set no matter what the RESPONSE-FLAG field says 🌈

10.4.1. Response Messages πŸ¦‹

whenever a data message with DATA-TYPE SCS-DATA or 3270-DATA comes in, the receiver must try to process the data in its data portion. then it decides whether it should send a data message with DATA-TYPE RESPONSE πŸ€” if the message it just processed had RESPONSE-FLAG set to NO-RESPONSE, or it had ERROR-RESPONSE and there were no errors while processing, then no RESPONSE-type message gets sent. otherwise, a data message should go out with the header DATA-TYPE field set to RESPONSE, and the SEQ-NUMBER field copied from the message this response is for. the RESPONSE-FLAG in this header must be either POSITIVE-RESPONSE or NEGATIVE-RESPONSE πŸŽ€ a POSITIVE-RESPONSE should be sent if the previous message's header said ALWAYS-RESPONSE and there were no errors processing the data. a NEGATIVE-RESPONSE should be sent when:

  1. the previously processed message specified ERROR-RESPONSE or ALWAYS-RESPONSE, and
  2. some kind of error happened while processing the data.

normally only the client builds and sends these RESPONSE messages πŸ’– a negative response sent from the client to the server is the same thing as a Unit Check Status [7]. everything about device status and sense codes in this section depends on [7] 🌸

the data portion of a RESPONSE message has to be one byte of binary data. that byte tells you more detail about how the previously received data message went πŸ‘‘ here are the possible values:

For a RESPONSE-FLAG value of POSITIVE-RESPONSE -

             Value            Meaning
             -----            -------
             0x00      Successful completion (when sent by the client,
                       this is equivalent to "Device End").

For a RESPONSE-FLAG value of NEGATIVE-RESPONSE -

             Value            Meaning
             -----            -------
             0x00      An invalid 3270 command was received
                       (equivalent to "Command Reject").

             0x01      Printer is not ready (equivalent to
                       "Intervention Required").

             0x02      An illegal 3270 buffer address or order
                       sequence was received (equivalent to
                       "Operation Check").

             0x03      Printer is powered off or not connected
                       (equivalent to "Component Disconnected").

when the server gets any of those responses, it should pass the right info along to the host application πŸ“ which info is right depends on whether the server represents an SNA or a non-SNA device 🧚

an SNA server should pass a POSITIVE-RESPONSE from the client along to the host application as an SNA positive Response Unit ✨ it should turn a NEGATIVE-RESPONSE from the client into an SNA negative Response Unit, with the Sense Data Indicator bit on and one of these sense codes:

          RESPONSE-FLAG        Equivalent        SNA Sense Code
          -------------        ----------        --------------
              0x00           Command Reject        0x10030000

              0x01        Intervention Required    0x08020000

              0x02           Operation Check       0x10050000

              0x03        Component Disconnected   0x08310000

a non-SNA server should pass a POSITIVE-RESPONSE from the client along by turning the Device End Status bit on πŸ¦‹ for a NEGATIVE-RESPONSE, it should turn on the Unit Check Status Bit, and also turn on either the Command Reject, Intervention Required, or Operation Check Sense bit when it's responding to the Sense command πŸ’€

when Intervention Required or Component Disconnected gets passed from the server to the host application, the host would normally hold off on sending any more data to the printer πŸ™ˆ once the error at the client has been fixed, the client must send the server a data message with DATA-TYPE set to REQUEST and REQUEST-FLAG set to ERR-COND-CLEARED. this message has no data portion, so no cap it's super short 🫢 when the server gets it, it should pass the right info along to the host application so the host can start sending printer output again. again, what that info looks like depends on whether the server is SNA or non-SNA 🌈

an SNA server should reflect an ERR-COND-CLEARED to the host application by sending an SNA LUSTAT RU with one of these sense codes:

  • if the previous error condition was an Intervention Required, the server should send sense code 0x00010000
  • if the previous error condition was Component Disconnected, the server should send sense code 0x082B0000

a non-SNA server should set the matching bits in the Ending Status and Sense Condition bytes πŸ’œ

10.5. The SYSREQ Function 🌸

this one can only be supported when the TN3270E server represents SNA devices ✨

agreeing to support it means you have to support this TN3270E header value:

             Header field         Value
             ------------         -----
              DATA-TYPE          SSCP-LU-DATA

the 3270 SYSREQ key can be super useful in an SNA environment when the ATTN key isn't enough to end a process πŸ‘‘ (see "The 3270 ATTN Key" section for more info 🫢)

10.5.1 Background ✨

Okay so, in SNA there are two sessions going on at once, bestie πŸ’… The first is the PLU-SLU session, between the host application (the PLU, or Primary Logical Unit) and the TN3270E server standing in for the client (the SLU, or Secondary Logical Unit). This is where all the normal communication happens πŸ¦‹ The second is the SSCP-LU session, between the host telecommunications access method (the SSCP, or System Services Control Point) and the SLU. It carries control info and is basically invisible to the user πŸ™ˆ Normal 3270 data stream orders are not allowed in this data. For more info, see [7] πŸ“–

Next up, the terminal display and keyboard are usually "owned" by the PLU-SLU session, so anything the user types gets sent to the host application ⌨️ The SYSREQ key toggles ownership between the PLU-SLU session and the SSCP-LU session, so the user can press SYSREQ and talk straight to the host SSCP πŸ‘‘ From there they can enter any valid Unformatted Systems Services commands, which are defined in the USS table associated with the SLU. The most common one is LOGOFF, which asks the SSCP to immediately end the PLU-SLU session. Users usually do this when the host app has totally frozen up πŸ’€

While the keyboard and display belong to the SSCP-LU session, no data can flow in either direction on the PLU-SLU session 🚫 Once the user is "in" SSCP-LU, they can press SYSREQ again to switch back to PLU-SLU ✨

10.5.2 TN3270E Implementation of SYSREQ πŸ™Œ

Some TN3270E servers can fully support the SYSREQ key, because they're allowed to send USS commands on the SSCP-LU session. Other servers live in an environment that doesn't let them send USS commands to the SSCP, so full support is impossible for them 😭 For those servers, TN3270E provides emulation of a minimal subset of functions: the SYSREQ-then-LOGOFF sequence that lots of users rely on to immediately end the PLU-SLU session.

The Telnet Abort Output (AO) command is the mechanism used for SYSREQ support in TN3270E. Why? In a real SNA session, once SYSREQ is pressed, the host application can't send any more output to the terminal (unless SYSREQ gets pressed a second time), but the user's process keeps on executing 🧠

To implement SYSREQ support, TN3270E clients that agreed to the SYSREQ function should provide a key (or combo of keys) that maps to the 3270 SYSREQ key. When the user presses it, the client should transmit a Telnet AO command to the server πŸŽ€

When a TN3270E server that agreed to the SYSREQ function gets that AO command, it should enter what we'll loosely call "suspended mode" for the connection 🫧 If a server that did not agree to SYSREQ receives an AO command, it should simply ignore it. Any attempt by the host application to send data to the client while the connection is "suspended" should get a negative response from the server, sense code 0x082D, which means an "LU Busy" condition ❌ The server should not transmit anything to the client on behalf of the host application. While the connection is "suspended," any data messages exchanged between client and server should have the DATA-TYPE flag set to SSCP-LU-DATA. The data stream is as defined in [7], specifically the section entitled "Operation in SSCP-SLU Session." πŸ“œ

At this point, what happens next depends on whether the server is allowed to send USS commands on the SSCP-LU session. Servers that can should just act as a vehicle for passing USS commands and responses between the client and the SSCP πŸš—

Servers that are not allowed to send USS commands on the SSCP-LU session should behave like this:

  • If the user transmits the string LOGOFF (upper or lower case), the server should send an Unbind SNA RU to the host application. This results in termination of the PLU-SLU session. If the BIND-IMAGE function was agreed upon, the server should also send a data message to the client with the DATA-TYPE flag set to UNBIND and the data portion set to 0x01 πŸ‘‹
  • If the user transmits anything other than LOGOFF, the server should respond to the client with the string COMMAND UNRECOGNIZED. The server should not send anything to the host application on behalf of the client πŸ™…

Regardless of which kind of server is present (whether or not it may send USS commands on the SSCP-LU session), while the connection is suspended, the user can press the "SYSREQ" key again. That sends another AO to the server πŸ” The server should then send an LUSTAT RU to the host application with a value of 0x082B, which means "presentation space integrity lost." After that, the server "un-suspends" the Telnet connection to the client, so the host application can once again send data to the client πŸŽ‰


11. The 3270 ATTN Key πŸ’₯

In lots of SNA environments, host applications read the 3270 ATTN key as a way of saying "I want to interrupt the current process" βœ‹ The Telnet Interrupt Process (IP) command was defined for exactly that purpose, so it gets used to implement support for the 3270 ATTN key. This takes two things:

  • TN3270E clients should provide, as part of their keyboard mapping, a single key or a combo of keys that map to the 3270 ATTN key. When the user presses it, the client should transmit a Telnet IP command to the server ⌨️
  • TN3270E servers should translate the IP command received from a TN3270E client into the appropriate form and pass it along to the host application as an ATTN key. In other words, the server representing an SLU in an SNA session should send a SIGNAL RU to the host application πŸ“¨

The ATTN key isn't supported in a non-SNA environment, so a TN3270E server representing non-SNA 3270 devices should ignore any Telnet IP commands it gets from a client πŸ™ˆ


12. 3270 Structured Fields 🎨

3270 structured fields offer a much wider range of features than "old-style" 3270 data, like graphics, partitions and IPDS printer data streams πŸ–¨οΈ It would be unreasonable to expect every TN3270E client to support every possible structured field function, but there still has to be a way for clients that can support some or all of them to say so πŸ™‹

The design of 3270 structured fields gives us a neat way to share the level of support (including no support) for the different structured field functions. It's the Read Partition Query command, sent from the host application to the device. The device answers with one or more Query Reply structured fields that list which structured field functions it supports, if any πŸ’…

The Query Reply also covers some device capabilities that don't need structured fields, like extended color support and extended highlighting capability 🌈 Most host applications use Read Partition Query to figure out exactly what a device can do once there's been some sign that the device supports the "extended data stream" ✨

So, all TN3270E clients that negotiate a terminal device-type with a -E suffix, the DYNAMIC terminal type, or a printer device-type must be able to respond to a Read Partition Query command 🫢 Note that these clients must support both the Read Partition Query (Type 02) and all forms of the Read Partition Query List (Type 03) πŸ”₯


13. Implementation Guidelines πŸ› οΈ

13.1 3270 Data Stream Notes 🧩

Implementors of TN3270E clients should know that the command codes for the various 3270 Read and Write commands have different values depending on how the server is connected to the host (local versus remote, SNA versus non-SNA). If clients want to be compatible with the widest range of servers, they should be coded to check for the various possible values. See [7] for further details πŸ”

13.2 Negotiation of the TN3270E Telnet Option 🀝

TN3270E is a Telnet Option governed by [8], so both client and server are free to try to start negotiation by sending a DO TN3270E command. But just like with the Telnet DO TERMINAL-TYPE, the server is normally the one that sends DO TN3270E, and the client responds with a WILL or a WON'T TN3270E πŸŽ€

13.3 A "Keep-alive" Mechanism πŸ’“

In many environments, it's super helpful to have a mechanism that gives timely notice when a 3270 session is lost 😱 TN3270E doesn't require either clients or servers to use any form of keep-alive mechanism, but if you want one, these guidelines are for you.

There are at least three possible ways to provide a keep-alive mechanism in TN3270E: the TCP Keepalive, the Telnet IAC NOP command [8], and the Telnet DO TIMING-MARK option [9]. Each method has its own advantages and disadvantages πŸ€“ It is recommended that TN3270E clients and servers that support keep-alives support all three methods, and that both sides always respond to TIMING-MARKs 🫧

Both clients and servers could be configured to "actively" implement keep-alives. That means both sides could send a TIMING-MARK or a NOP, or issue a TCP Keepalive, to find out whether the partner is still alive πŸ’– Or, network administrators may prefer to configure only one side to send keep-alives. In that case, the other side is a "passive" participant that just responds to the keep-alives it receives πŸ¦‹

Implementors who want their code to be capable of being an "active" keep-alive participant should make their client or server configurable, so administrators can set which keep-alive mechanism (if any) gets used and how often πŸŽ›οΈ

When a session that uses keep-alives fails, both parties should make the proper notifications. A client should give the user some indication of the failure, such as an error code in the Operator Information Area of the screen ⚠️ A server should notify the host application that the session has been terminated, for example by sending an UNBIND with type CLEANUP in an SNA environment 🧹

13.4 Examples ✨

okay bestie, examples time 🧚 these show the handshake step by step, so you can see exactly who says what and when πŸ’…

First up, a TN3270E-capable server meets a plain old tn3270 client. The client doesn't speak TN3270E, so it's basically just vibing on regular telnet πŸ¦‹

     Server:  IAC DO TN3270E
     Client:  IAC WON'T TN3270E
     Server:  IAC DO TERMINAL-TYPE
     Client:  IAC WILL TERMINAL-TYPE
     Server:  IAC SB TERMINAL-TYPE SEND IAC SE
     Client:  IAC SB TERMINAL-TYPE IS IBM-3278-2 IAC SE
     Server:  IAC DO EOR IAC WILL EOR
     Client:  IAC WILL EOR IAC DO EOR
     Server:  IAC DO BINARY IAC WILL BINARY
     Client:  IAC WILL BINARY IAC DO BINARY
        (3270 data stream is exchanged)

Next, both sides are TN3270E-capable and they set up a generic pool (non-specific) terminal session. No device name is requested here, so the server just hands out any available terminal 🌸

     Server:  IAC DO TN3270E
     Client:  IAC WILL TN3270E
     Server:  IAC SB TN3270E SEND DEVICE-TYPE IAC SE
     Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3278-2 IAC SE
     Server:  IAC SB TN3270E DEVICE-TYPE IS IBM-3278-2 CONNECT
                     anyterm IAC SE
     Client:  IAC SB TN3270E FUNCTIONS REQUEST RESPONSES IAC SE
     Server:  IAC SB TN3270E FUNCTIONS IS RESPONSES IAC SE
        (3270 data stream is exchanged)

Now the client asks for a specific device-name, myterm. Notice that BIND-IMAGE shows up in the FUNCTIONS exchange this time πŸŽ€

     Server:  IAC DO TN3270E
     Client:  IAC WILL TN3270E
     Server:  IAC SB TN3270E SEND DEVICE-TYPE IAC SE
     Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3278-5-E
                     CONNECT myterm IAC SE
     Server:  IAC SB TN3270E DEVICE-TYPE IS IBM-3278-5-E CONNECT
                     myterm IAC SE
     Client:  IAC SB TN3270E FUNCTIONS REQUEST RESPONSES
                     BIND-IMAGE IAC SE
     Server:  IAC SB TN3270E FUNCTIONS IS RESPONSES BIND-IMAGE
                     IAC SE
        (3270 data stream is exchanged)

This one is giving "I'll take a resource, you pick the device" ✨ The client asks for a resource-name, pool1, and the server comes back with a device-name of its own choosing, term0013.

    Server:  IAC DO TN3270E
    Client:  IAC WILL TN3270E
    Server:  IAC SB TN3270E SEND DEVICE-TYPE IAC SE
    Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3278-5-E
                    CONNECT pool1 IAC SE
    Server:  IAC SB TN3270E DEVICE-TYPE IS IBM-3278-5-E CONNECT
                    term0013 IAC SE
    Client:  IAC SB TN3270E FUNCTIONS REQUEST BIND-IMAGE IAC SE
    Server:  IAC SB TN3270E FUNCTIONS IS BIND-IMAGE IAC SE
       (3270 data stream is exchanged)

Here's a retry story πŸ™ˆ The client first asks for myterm, but the server says no because it's already in use (DEVICE-IN-USE). So the client tries again with a different name, herterm, and this time it works.

     Server:  IAC DO TN3270E
     Client:  IAC WILL TN3270E
     Server:  IAC SB TN3270E SEND DEVICE-TYPE IAC SE
     Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3278-5
                     CONNECT myterm IAC SE
     Server:  IAC SB TN3270E DEVICE-TYPE REJECT REASON
                     DEVICE-IN-USE IAC SE
     Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3278-2
                     CONNECT herterm IAC SE
     Server:  IAC SB TN3270E DEVICE-TYPE IS IBM-3278-2 CONNECT
                     herterm IAC SE
     Client:  IAC SB TN3270E FUNCTIONS REQUEST RESPONSES IAC SE
     Server:  IAC SB TN3270E FUNCTIONS IS RESPONSES IAC SE
        (3270 data stream is exchanged)

Printer sessions get a little extra drama πŸ–¨οΈ In this one the client asks for a specific printer, myprt, and some 3270 function negotiation has to happen before everyone agrees on how things work.

     Server:  IAC DO TN3270E
     Client:  IAC WILL TN3270E
     Server:  IAC SB TN3270E SEND DEVICE-TYPE IAC SE
     Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3287-1 CONNECT
                     myprt IAC SE
     Server:  IAC SB TN3270E DEVICE-TYPE IS IBM-3287-1 CONNECT
                     myprt IAC SE
     Client:  IAC SB TN3270E FUNCTIONS REQUEST DATA-STREAM-CTL IAC
     Server:  IAC SB TN3270E FUNCTIONS REQUEST DATA-STREAM-CTL
                     RESPONSES IAC SE
     Client:  IAC SB TN3270E FUNCTIONS REQUEST DATA-STREAM-CTL IAC
     Server:  IAC SB TN3270E FUNCTIONS IS DATA-STREAM-CTL IAC SE

        (3270 data stream is exchanged)

Okay, this one is a whole double feature πŸ‘‘ First the client gets a specific terminal, termxyz. Then it reconnects and asks for a printer that's the "partner" of that terminal, using ASSOCIATE.

     Server:  IAC DO TN3270E
     Client:  IAC WILL TN3270E
     Server:  IAC SB TN3270E SEND DEVICE-TYPE IAC SE
     Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3278-2 CONNECT
                     termxyz IAC SE
     Server:  IAC SB TN3270E DEVICE-TYPE IS IBM-3278-2 CONNECT
                     termxyz IAC SE
     Client:  IAC SB TN3270E FUNCTIONS REQUEST RESPONSES IAC SE
     Server:  IAC SB TN3270E FUNCTIONS IS RESPONSES IAC SE
        (3270 data stream is exchanged)
          .            .
          .            .
        (user decides to request a printer session,
         so client again connects to Telnet port on server)
     Server:  IAC DO TN3270E
     Client:  IAC WILL TN3270E
     Server:  IAC SB TN3270E SEND DEVICE-TYPE IAC SE
     Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3287-1
                     ASSOCIATE termxyz IAC SE
     Server:  IAC SB TN3270E DEVICE-TYPE IS IBM-3287-1 CONNECT
                     termxyz's-prt IAC SE
     Client:  IAC SB TN3270E FUNCTIONS REQUEST SCS-CTL-CODES
                     RESPONSES IAC SE
     Server:  IAC SB TN3270E FUNCTIONS IS SCS-CTL-CODES RESPONSES
                     IAC SE
        (3270 data stream is exchanged)

And the grand finale, same vibe but with a pool πŸ’œ The client asks for a resource-name, poolxyz, gets the terminal terma back from the server, and later comes back for terma's printer partner.

     Server:  IAC DO TN3270E
     Client:  IAC WILL TN3270E
     Server:  IAC SB TN3270E SEND DEVICE-TYPE IAC SE
     Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3278-5 CONNECT
                     poolxyz IAC SE
     Server:  IAC SB TN3270E DEVICE-TYPE IS IBM-3278-5 CONNECT
                     terma IAC SE
     Client:  IAC SB TN3270E FUNCTIONS REQUEST RESPONSES IAC SE
     Server:  IAC SB TN3270E FUNCTIONS IS RESPONSES IAC SE
        (3270 data stream is exchanged)
          .            .
          .            .
        (user decides to request a printer session,
         so client again connects to Telnet port on server)
     Server:  IAC DO TN3270E
     Client:  IAC WILL TN3270E
     Server:  IAC SB TN3270E SEND DEVICE-TYPE IAC SE
     Client:  IAC SB TN3270E DEVICE-TYPE REQUEST IBM-3287-1
                     ASSOCIATE terma IAC SE
     Server:  IAC SB TN3270E DEVICE-TYPE IS IBM-3287-1 CONNECT
                     terma's-prt IAC SE
     Client:  IAC SB TN3270E FUNCTIONS REQUEST SCS-CTL-CODES
                     RESPONSES IAC SE
     Server:  IAC SB TN3270E FUNCTIONS IS SCS-CTL-CODES RESPONSES
                     IAC SE
        (3270 data stream is exchanged)

14. Security Considerations ✨

Real talk, bestie, this part matters πŸ”₯ These telnet extensions don't add any security features on top of ordinary telnet. So a TN3270E session is exactly as secure as a regular telnet session, and no more.

Someday, once standard authentication and/or privacy mechanisms for telnet are defined, TN3270E might be able to use those too. Authentication is especially important for one question: whether a given user should be allowed to "use" a specific terminal or printer device-name.

Heads up: a TN3270E session is no more secure than an ordinary telnet session, so don't assume your 3270 traffic is protected just because it's TN3270E πŸ™ˆ

15. References ✨

[1] Rekhter, J., "Telnet 3270 Regime Option", RFC 1041, January 1988.

[2] VanBokkelen, J., "Telnet Terminal-Type Option", RFC 1091, February 1989.

[3] Postel, J., and J. Reynolds, "Telnet Binary Transmission", STD 27, RFC 856, May 1983.

[4] Postel, J., "Telnet End of Record Option", RFC 885, December 1983.

[5] "3270 Information Display System - Data Stream Programmer's Reference", publication number GA24-0059, IBM Corporation.

[6] "SNA Formats", publication number GA27-3136, IBM Corporation.

[7] "3174 Establishment Controller Functional Description", publication number GA23-0218, IBM Corporation.

[8] Postel, J., and J. Reynolds, "Telnet Protocol Specification", STD 8, RFC 854, May 1983.

[9] Postel, J., and J. Reynolds, "Telnet Timing Mark Option", STD 31, RFC 860, May 1983.

[10] J. Penner, "TN3270 Current Practices", RFC 1576, January, 1994.


16. Author's Note πŸ’œ

Portions of this document were drawn from the following sources:

  • A White Paper written by Owen Reddecliffe, WRQ Corporation, October 1991.
  • Experimental work on the part of Cleve Graves and Michelle Angel, OpenConnect Systems, 1992 - 1993.
  • Discussions at the 1993 IETF meetings.
  • Discussions on the "TN3270E" list, 1993-94 and 1997.

17. Author's Address πŸŽ€

Bill Kelly
Division of University Computing
144 Parker Hall
Auburn University, AL  36849

Phone: (334) 844-4512
EMail: kellywh@mail.auburn.edu

Okay, the legal bit, and it has to stay word for word, so here it is in full ✨

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

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

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

πŸ“¦ where this page comes from