RFC 732

Telnet Data Entry Terminal option

๐Ÿ“… published September 1977, from ietf

Telnet Data Entry Terminal Option ๐ŸŽ€

Okay bestie, this is RFC 732 ๐Ÿ’– (header stamp: NWG/RFC# 732, DAY 13-Sep-77 18:38, NIC 41762). It's by John Day from the Network Working Group, dated 12 September 1977, and it's the Telnet Data Entry Terminal Option (DET, option code 20). It obsoletes RFC 731 ๐Ÿฆ‹. The title block lists no updates, and it doesn't name a category, so I'm not going to guess one โœจ


1. Command Name and Code โœจ

DET             20

2. Command Meanings ๐Ÿ’…

Here's how the four DET commands work, babe ๐Ÿซถ

IAC WILL DET

The sender of this command REQUESTS or AGREES to send and receive subcommands to control the Data Entry Terminal.

IAC WONT DET

The sender of this command REFUSES to send and receive subcommands to control the Data Entry Terminal.

IAC DO DET

The sender of this command REQUESTS or AGREES to send and receive subcommands to control the Data Entry Terminal.

IAC DONT DET

The sender of this command REFUSES to send and receive subcommands to control the Data Entry Terminal.


The DET Subcommand Classes ๐ŸŒธ

The DET option has five classes of subcommands, and it's giving organized ๐Ÿงš They do these jobs:

  1. Set up the requirements and capabilities of the application and the terminal
  2. Format the screen
  3. Control the edit functions
  4. Control the erasure functions
  5. Control the transmission functions

The subcommands for each of these are described below.


The Network Virtual Data Entry Terminal (NVDET) ๐Ÿฆ‹

The NVDET is a keyboard plus a rectangular display ๐Ÿ’œ The keyboard can make every character in the ASCII character set. Some keyboards also have function keys, and pressing one sends an FN subcommand.

(Most DETs support peripherals like a paper tape reader or a printer, but this option doesn't cover them. Peripheral support should be treated as a separate option. ๐Ÿ™ˆ)

The screen is a rectangle that is M characters wide by N lines tall ๐Ÿ“บ The values of M and N come from negotiating the Output Line Width and Output Page Size options, respectively. The next writing position (x,y) is marked by a special display character called the cursor, where x is the character position and y is the line position on the screen. The cursor can move anywhere on the screen without messing up the characters already there.

Real terminals handle cursor addressing in lots of different ways, which is a lot of chaos ngl ๐Ÿ˜ญ To keep implementing this easy, the protocol supports two topologies (the finite plane and the helical torus) and three addressing methods ((x,y); x and y; and relative increments). The finite plane with absolute addressing is the least ambiguous and easiest to translate to and from the others, so it's the default the NVDET uses. The torodial form, with either relative or absolute addressing, is there for convenience โœจ

The NVDET can also define fields with special attributes on the screen. For example, characters typed into these fields can be shown brighter, highlighted with reverse video or blinking, or protected from being changed by the user. Protection is one of the most used features for apps where the DET shows a form for the user to fill in ๐Ÿ‘‘

The NVDET uses Telnet option subnegotiations for all of its functions. None of the ASCII characters in the data stream are used to define these functions, so the DET option can run in a "raw" or even "rare" mode ๐Ÿ”ฅ If the application knows what kind of terminal is on the other end, it can send the ASCII characters needed to control functions the option or implementation doesn't support. In general, keeping all NVDET functions out of the data stream gives you better flexibility ๐Ÿ’…


Facility Functions (for detailed semantics see Section 5.) ๐ŸŽ€

Here's the grammar for facility functions:

IAC SB DET <DET facility subcommand><facility map> IAC SE

The <DET facility subcommand> is one 8-bit byte that says which class of facilities is being described. The <facility map> is a field of one or two 8-bit bytes with flags for the facilities the sender requires or wants. The bits of a facility map are numbered from the right, starting at zero. So if bit 2 is set, the field has a decimal value of 4 ๐Ÿ“ The values work like this:

EDIT FACILITIES (subcommand code: 1) ๐Ÿ’–

facility cmd:  EDIT FACILITIES                    subcommand code: 1

  facility map:                              bit numbers

    Toroidal Cursor Addressing                  6
    Incremental Cursor Addressing               5
    Read Cursor Address                         4
    Line Insert/Delete                          3
    Char Insert/Delete                          2
    Back Tab                                    1
    Positive Addressing only                    0

Here's what each bit means:

  • If the Toroidal Cursor Addressing bit is set, the sender requests or provides support for the SKIP TO LINE and SKIP TO CHAR subcommands.
  • If the Incremental Cursor Addressing bit is set, the sender requests or provides support for the UP, DOWN, LEFT, and RIGHT subcommands.
  • If the Read Cursor bit is set, the sender requests or provides the READ CURSOR subcommand.
  • If the Line Insert/Delete bit is set, the sender requests or provides support for the LINE INSERT and LINE DELETE subcommands.
  • If the Char Insert/Delete bit is set, the sender requests or provides support for the CHAR INSERT and CHAR DELETE subcommands.
  • If the Back Tab bit is set, the sender requests or provides support for the BACK TAB subcommand.
  • If the Positive Addressing bit is set, the sender is telling the receiver that it can only move the cursor in the positive direction. (Terminals with this property also have a Home function to get back to the beginning. ๐ŸŒˆ)

ERASE FACILITIES (subcommand code: 2) ๐Ÿซง

facility cmd:  ERASE FACILITIES                  subcommand code:  2

  facility map:                                bit numbers

    Erase Field                                     4
    Erase Line                                      3
    Erase Rest of Screen                            2
    Erase Rest of Line                              1
    Erase Rest of Field                             0

If a bit in this facility map is set, the sender requests or provides the facility that bit stands for. For a more complete rundown of each of these, check the Erase Functions section below โœจ

TRANSMIT FACILITIES (subcommand code: 3) ๐Ÿ“ก

facility cmd:  TRANSMIT FACILITIES               subcommand code:  3

  facility map:                      bit numbers

    Data Transmit                         5
    Transmit Line                         4
    Transmit Field                        3
    Transmit Rest of Screen               2
    Transmit Rest of Line                 1
    Transmit Rest of Field                0

If a bit in this facility map is set, the sender requests or provides the facility that bit stands for. For a more complete rundown, check the Transmit Functions section below ๐Ÿฆ‹

FORMAT FACILITIES (subcommand code: 4) ๐ŸŒท

facility cmd:  FORMAT FACILITIES                 subcommand code:  4

  facility map:                               bit numbers

    FN                                 byte 0      7
    Modified                                       6
    Light Pen                                      5
    Repeat                                         4
    Blinking                                       3
    Reverse Video                                  2
    Right Justification                            1
    Overstrike                                     0
    Protection On/Off                  byte 1      6
    Protection                                     5
    Alphabetic-only Protection                     4
    Numeric-only Protection                        3
    Intensity                                      0-2

Here's the breakdown of the format bits, bestie ๐Ÿซถ

  • If the FN bit is set, the sender requests or provides the FN subcommand.
  • If the Modified bit is set, the sender requests or provides the ability to mark fields that have been modified, and supports the TRANSMIT MODIFIED subcommand.
  • If the Light Pen bit is set, the sender requests or provides support for a light pen, including the Pen Selectable attribute of the DATA FORMAT subcommand.
  • If the Repeat bit is set, the sender requests or provides the REPEAT subcommand.
  • If the Blinking bit is set, the sender requests or provides the ability to highlight a string of characters by making them blink.
  • If the Reverse Video bit is set, the sender requests or provides the ability to highlight a string of characters by "reversing the video image." So if characters normally show as black on white, they flip to white on black, or the other way around ๐Ÿ˜ญ
  • If the Right Justification bit is set, the sender requests or provides the ability to right-justify entered data in a field.
  • If the Overstrike bit is set, the sender requests or provides the ability to layer one character over another on the screen, kind of like a hard copy terminal when the print mechanism hits the same spot on paper with different characters ๐Ÿ’€
  • If the Protection On/Off bit is set, the sender requests or provides the ability to turn field protection on and off.
  • If the Protection bit is set, the sender requests or provides the ability to protect certain strings shown on the screen from being changed by the terminal's user. Setting this bit also implies that the ERASE UNPROTECTED, DATA TRANSMIT, FIELD SEPARATOR, and TRANSMIT UNPROTECTED subcommands (see below) are supported.
  • If the Alphabetic-only Protection bit is set, the sender requests or provides the ability to limit the terminal's user so they can only enter alphabetic data into certain areas of the screen.
  • If the Numeric-only Protection bit is set, the sender requests or provides the ability to limit the terminal's user so they can only enter numeric data into certain areas of the screen.

The three bits of the Intensity field hold a positive binary integer for how many levels of intensity the sender requests or provides when showing data. Here's how to read that value:

1        one visible intensity
2        two intensities; normal and bright
3        three intensities; off, normal, and bright
>3       >3 intensities; off, and the remaining levels
         proportioned from dimmest to brightest intensity.

For all of the above commands, if the appropriate bit in <facility map> is not set, then the sender does not request or provide that facility ๐Ÿ™ˆ


Editing Functions โœ๏ธ

Here's the editing grammar, the MOVE CURSOR subcommand:

IAC SB DET MOVE CURSOR <x><y> IAC SE              subcommand code: 5

Where <x> is an 8-bit byte with a positive binary integer for the character position of the cursor, and <y> is an 8-bit byte with a positive binary integer for the line position of the cursor ๐Ÿ“

This subcommand moves the cursor to the absolute screen address (x,y), and it has these boundary conditions:

  if x>M-1, set x=M-1 and send an ERROR subcommand
Heads up, this is only part one, so the cursor boundary rules keep going in the next part ๐Ÿ’œ

if y>N-1, set y=N-1 and send an ERROR subcommand ๐Ÿ’… This is how we keep the cursor from going off the edge of the screen. The screen is a finite plane, bestie ๐Ÿฆ‹

This describes a finite plane topology on the screen.
IAC SB DET SKIP TO LINE <y> IAC SE                subcommand code: 6

Where <y> is a positive 8-bit binary number ๐Ÿ”ข. This subcommand moves the cursor to the absolute screen line y. x stays exactly where it is ๐Ÿซถ. For values of y>N-1, the math wraps around like this:

y = y mod N
IAC SB DET SKIP TO CHAR <x> IAC SE                subcommand code: 7

Where <x> is a positive 8-bit binary number โœจ. This subcommand moves the cursor to the absolute character position x. y stays the same, UNLESS x>M-1, and then it's giving math time ๐Ÿงฎ:

x' = (x mod M)
y' = (y+(x DIV N))
where x' and y' are the new values of the cursor.

These last two subcommands make a toroidal topology on the screen ๐Ÿฉ (yes, like a donut, it's so iconic ๐ŸŒˆ).

IAC SB DET UP IAC SE                              subcommand code: 8
IAC SB DET DOWN IAC SE                            subcommand code: 9
IAC SB DET LEFT IAC SE                           subcommand code: 10
IAC SB DET RIGHT IAC SE                          subcommand code: 11

These are convenience subcommands for some terminals ๐Ÿ’–. UP, DOWN, LEFT, and RIGHT are defined as:

UP:     (x,y)=(x, y-1 mod N)
DOWN:   (x,y)=(x, y+1 mod N)
LEFT:   (x,y)=(x-1, y); if x=0 then x-1 = 0

RIGHT:  (x,y)=(x+1 mod M, y) and y = y+1 if x+1>M-1
Note: DOWN, LEFT, and RIGHT can NOT always be swapped out for the ASCII codes for linefeed, backspace, and space ๐Ÿ™ˆ. Those ASCII codes are format effectors, while these are cursor controls. Not the same thing, bestie!
IAC SB DET HOME IAC SE                           subcommand code: 12

This one parks the cursor at (0,0) ๐Ÿ . It's the same as MOVE CURSOR 0,0, or the combo SKIP TO LINE 0, SKIP TO CHAR 0. It's here just for convenience, since most terminals have HOME as its own key ๐ŸŽ€.

IAC SB DET LINE INSERT IAC SE                    subcommand code: 13

This one inserts a line of spaces between line y (the current line, where the cursor is) and line y-1 ๐ŸŒธ. Lines y through N-2 move down one line, so line y becomes line y+1, y+1 becomes y+2, and so on, until N-2 becomes N-1. Line N-1 gets yeeted off the bottom of the screen ๐Ÿ‘‹. The cursor doesn't move.

IAC SB DET LINE DELETE IAC SE                    subcommand code: 14

This one deletes line y, where y is the cursor's current line ๐Ÿ—‘๏ธ. Lines y+1 through N-1 move up one line, so line y+1 becomes line y, y+2 becomes y+1, and so on, until N-1 becomes N-2. The N-1st line position gets set to all spaces ๐Ÿซง. The cursor position stays unchanged.

IAC SB DET CHAR INSERT IAC SE                    subcommand code: 15

This one inserts the next character in the data stream between the xth and x-1st characters, where x is the cursor's current character position ๐Ÿ’…. The xth through M-2nd characters on the line shift one character position to the right. The new character goes into the vacated xth spot โœจ. The M-1st character gets lost ๐Ÿ˜ญ. The cursor position stays unchanged.

IAC SB DET CHAR DELETE IAC SE                    subcommand code: 16

This one deletes the character at the x-th position on the screen ๐Ÿช„. That character gets removed, and characters x+1 through M-1 shift one character position to the left, becoming the x-th through M-2nd characters. The M-1st character position is left empty. (Most terminals will set it to a NUL or space, fr fr.) The cursor position stays unchanged.

IAC SB DET READ CURSOR IAC SE                    subcommand code: 17

This one asks the receiver to send back the cursor's present position to the sender ๐Ÿ“ฎ. It's a little "where are you at?" text, honestly iconic ๐Ÿ’œ.

IAC SB DET CURSOR POSITION <x><y> IAC SE         subcommand code: 18

Where <x> and <y> are positive 8-bit binary integers ๐Ÿ”ข. The Telnet implementation sends this in response to a READ CURSOR subcommand, so the other side knows where the cursor is ๐Ÿงš. Note: x is less than M and y is less than N.

IAC SB DET REVERSE TAB IAC SE                    subcommand code: 19

This one moves the cursor back to the previous tab position โฌ…๏ธ. If there isn't one on the current line, the cursor moves to the previous line, and keeps going until it finds a tab or hits the address (0,0) ๐ŸŒˆ. When field protection is on, the cursor goes to the beginning of the preceding unprotected field ๐Ÿ”.

Transmit Functions (For detailed semantics see Section 5.)

IAC SB DET TRANSMIT SCREEN IAC SE                subcommand code: 20

This makes the terminal transmit every character on the screen, from (0,0) to (M-1,N-1) ๐Ÿ“ค. The cursor ends up at (0,0) when it's done ๐Ÿ.

IAC SB DET TRANSMIT UNPROTECTED IAC SE           subcommand code: 21

This makes the terminal transmit every character in unprotected fields, from (0,0) to (M-1,N-1) ๐Ÿ”“. The unprotected fields are separated by the field separator subcommand ๐Ÿงฉ. When it's done, the cursor is at (0,0), or at the beginning of the first unprotected field ๐ŸŽฏ.

IAC SB DET TRANSMIT LINE IAC SE                  subcommand code: 22

This makes the terminal transmit all data on the yth line, where y is the cursor's present line ๐Ÿ“. Data goes from character position (0,y) to the end-of-line or position (M-1,y), whichever comes first. After the transmission, the cursor sits one character position after the end-of-line condition, or at the beginning of the next line, (0,y+1) ๐Ÿ’ซ.

IAC SB DET TRANSMIT FIELD IAC SE                 subcommand code: 23

This makes the terminal transmit all data in the field the cursor is currently in ๐Ÿ“ฆ. When it's done, the cursor is one character position after the end of the field. But if that position is protected, the cursor goes to the beginning of the next unprotected field ๐Ÿฆ‹.

IAC SB DET TRANSMIT REST OF SCREEN IAC SE        subcommand code: 24

This makes the terminal transmit every character on the screen from position (x,y) to (M-1,N-1), or until the end of text ๐ŸŒŠ. (x,y) is the cursor's current position. After it's done, the cursor is one character position after the last text character, or at (0,0) if the last filled character position is (M-1,N-1) ๐Ÿ”„.

IAC SB DET TRANSMIT REST OF LINE IAC SE          subcommand code: 25

This makes the terminal transmit every character on the yth line, from position (x,y) to the end of the line or (M-1,y), whichever comes first ๐Ÿงต. (x,y) is the cursor's current position. Afterwards, the cursor is one character position after the last character of the line, or at the first character of the next line ๐ŸŒŸ.

IAC SB DET TRANSMIT REST OF FIELD IAC SE         subcommand code: 26

This makes the receiver transmit the rest of the characters in the field the cursor is currently in ๐ŸŽ. When it's done, the cursor is at the beginning of the next field ๐Ÿƒโ€โ™€๏ธ.

IAC SB DET TRANSMIT MODIFIED IAC SE              subcommand code: 27

This makes the receiver transmit ONLY the fields that have the modified attribute set โœ๏ธ. The cursor position stays unchanged after the operation ๐Ÿ’œ.

IAC SB DET DATA TRANSMIT <x><y> IAC SE           subcommand code: 28

This one goes in front of data the terminal sends in response to a user action or a TRANSMIT command ๐Ÿ“จ. The parameters <x> and <y> show the cursor's starting position. Check out the Transmit Subcommands subsection in Section 5 for more details ๐Ÿ”. A DATA TRANSMIT subcommand can come before a whole transmission, with each field separated by the FIELD SEPARATOR subcommand, which is what you'd get in response to a TRANSMIT UNPROTECTED. Or it can come before each field, which is what you'd get in response to a TRANSMIT MODIFIED ๐Ÿซถ.

Erase Functions

IAC SB DET ERASE SCREEN IAC SE                   subcommand code: 29

This one removes all characters from the screen ๐Ÿงน. ALL fields get deleted, no matter their attributes ๐Ÿ’€. The cursor position after this is (0,0). Most terminals set the erased characters to either NUL or space characters ๐Ÿซง.

IAC SB DET ERASE LINE IAC SE                     subcommand code: 30

This one removes all characters on the yth line, where y is the line the cursor is on ๐Ÿงฝ. ALL fields get deleted, no matter their attributes. The cursor position after this is (0,y) ๐Ÿ“.

Note: This can be easily faked with the sequence LINE DELETE, LINE INSERT. BUT the order matters a lot, so no data gets lost off the bottom of the screen ๐Ÿ˜ฑ.
IAC SB DET ERASE FIELD IAC SE                    subcommand code: 31

This one removes all characters in the field the cursor is in ๐Ÿซง. The cursor ends up at the beginning of the field ๐ŸŽฏ.

IAC SB DET ERASE REST OF SCREEN IAC SE           subcommand code: 32

This one removes all characters from position (x,y) to (M-1,N-1) ๐ŸŒช๏ธ. ALL fields get deleted, no matter their attributes. The cursor position stays unchanged. This is the same as doing an ERASE REST OF LINE plus a LINE DELETE for lines greater than y ๐Ÿ”.

IAC SB DET ERASE REST OF LINE IAC SE             subcommand code: 33

This one removes all characters from position (x,y) to (M-1,y) ๐Ÿฉท. ALL fields get deleted, no matter their attributes. The cursor position stays unchanged.

IAC SB DET ERASE REST OF FIELD IAC SE            subcommand code: 34

This one removes all characters from position (x,y) to the end of the current field ๐Ÿชถ. The cursor position stays unchanged.

IAC SB DET ERASE UNPROTECTED IAC SE              subcommand code: 35

This one removes all characters on the screen in unprotected fields ๐Ÿ”“. The cursor ends up at (0,0), or, if that spot is protected, at the beginning of the first unprotected field ๐Ÿ’–.

Format Functions

IAC SB DET FORMAT DATA <format map><count> IAC SE
                                                 subcommand code: 36

Where <format map> is a two byte field holding these flags ๐ŸŒˆ:

  Byte 0
    Blinking                                 7
    Reverse Video                            6
    Right Justification                      5
    Protection                              3-4
    Intensity                               0-2
  Byte 1
    Modified                                1
    Pen Selectable                          0

Here's what those mean โœจ:

  • If the Blinking bit is set, the following field of <count> characters should get the Blinking attribute applied by the receiver ๐Ÿ’ซ.
  • If the Reverse Video bit is set, the following field of <count> characters should be displayed by the receiver with video reversed ๐Ÿ”„.
  • If the Right Justification bit is set, the input entered into the field of <count> characters should be right justified โžก๏ธ.

The Protection field is two bits wide, and it can be one of these values ๐Ÿ”:

  • 0 means no protection
  • 1 means protected
  • 2 means alphabetic only
  • 3 means numeric only

The protection attribute decides who gets to touch the field ๐Ÿ”’โœจ The other side can modify any character (no protection) ๐ŸŒธ, modify no characters at all (protected) ๐Ÿ™ˆ, enter only alphabetical characters, A-Z and a-z (alphabetic only) ๐Ÿ”ค, or enter only numerical characters, 0-9, +, ., and - (numeric only) ๐Ÿ”ข. This applies to the following field of <count> bytes ๐Ÿ’…

The Intensity field is 3 bits wide ๐ŸŽ€ and should be read like this:

  • Values 0-6 are a hint for how bright the characters should look when they're displayed or typed into the following field, which is <count> characters wide โœจ The number of brightness levels is supposed to be found earlier using the Format Facility subcommand. How these values map onto the available levels is left up to the implementors, so it's their call ๐Ÿงš
  • A value of 7 means the brightness is off. Any characters in or typed into the field should not be displayed ๐Ÿ™ˆ

If the Modified bit is set, the field counts as modified and gets sent back when a TRANSMIT MODIFIED subcommand comes in ๐Ÿ“

If the Pen Selectable bit is set, the field can be selected with the light pen ๐Ÿ–Š๏ธ

Note: Use of the light pen should be the subject of another Telnet option. Not this one, bestie ๐Ÿ’€

<count> is 2 bytes, read as a positive 16-bit binary integer. It's the number of characters following this command that it affects ๐Ÿ”ข

Data sent to the terminal or the Using Host for unwritten areas of the screen that fall outside the count should be displayed with the default values of the format map ๐ŸŒˆ Those defaults are No Blinking, Normal Video, No Justification, No Protection and Normal Intensity. For example, say a FORMAT DATA subcommand gets sent to the terminal with the attributes Blinking and Protected and a count of 5, followed by the string "Name: John Doe". Then "Name:" would be protected and blinking, but "John Doe" would not be ๐Ÿ˜ญ๐Ÿซถ

This subcommand formats data for display on the terminal's screen ๐Ÿ–ฅ๏ธ The <format map> describes the attributes that the field, <count> bytes wide, should have. The field starts at the cursor position when the command is acted upon. The next <count> displayable characters in the data stream fill the field, and REPEAT subcommands can come after to specify what goes in it โœจ If the sender specifies attributes that haven't been agreed upon with the Format Facility subcommand, the Telnet process should send an Error Subcommand to the sender, but still format the screen as if that bit hadn't been set. Not gonna lie, that's a very polite way to say "nice try" ๐Ÿ’…

IAC SB DET REPEAT <count><char> IAC SE           subcommand code: 37

where <count> is a positive 8-bit binary integer, and <char> is an 8-bit byte containing an ASCII character.

This subcommand does data compression for data sent to the terminal ๐Ÿ—œ๏ธ It encodes strings of identical characters as the character plus a count, which is honestly so efficient it's giving main character energy ๐Ÿ‘‘ The repeated characters may be part of a field specified

IAC SB DET SUPPRESS PROTECTION <negotiation> IAC SE
                                                 subcommand code: 38

where <negotiation> may have the values of the Telnet option negotiation:

251                 WILL
252                 WONT
253                 DO
254                 DONT

This subcommand suppresses the field protection in a non-destructive way ๐Ÿฆ‹ Lots of data entry terminals can turn protection on and off without changing what's on the screen or in the terminal's memory. So protection can go off and back on again without the form being retransmitted, which is so smart ๐Ÿง โœจ

The default setting of the option is that protection is on, in other words:

IAC SB DET SUPPRESS PROTECTION WONT IAC SE
IAC SB DET SUPPRESS PROTECTION DONT IAC SE

Negotiation of this subcommand follows the same rules as negotiations of the Telnet options ๐Ÿค

IAC SB DET FIELD SEPARATOR IAC SE                subcommand code: 39

When you're only sending the unprotected part of the screen, you need a way to mark where the fields start and stop ๐Ÿงฉ Existing DETs use all kinds of ASCII characters for this, like Tab, Group Separator, Unit Separator, and so on. To keep the NVDET transparent, this subcommand separates the fields instead. Clearly that comes with rather high overhead ๐Ÿ˜ฉ You can dodge that overhead by using the Byte Macro Option (see Appendix 3) ๐ŸŒธ


Miscellaneous Commands

IAC SB DET FN <code> IAC SE                      subcommand code: 40

where: <code> is one byte.

Lots of data-entry terminals have a set of "function" keys that send a one-character command to the server when pressed ๐ŸŽน This subcommand describes that facility. The values of the <code> field are defined by the user and the server. The option just provides the means to transfer the info, nothing more ๐Ÿซถ

IAC SB DET ERROR <cmd> <error code> IAC SE       subcommand code: 41

where:

  • <cmd> is a byte containing the subcommand code of the subcommand in error.
  • <error code> is a byte containing an error code.
  • (For a list of the defined error codes see Appendix 2.)

This subcommand lets DET option implementations report the errors they detect to the corresponding Telnet process ๐Ÿšจ Worth repeating: the philosophy of this option is that when an error is detected, it should be reported. But the implementation should still make its best effort to carry out the intent of the subcommand or data in error ๐Ÿ’–


3. Default and Minimal Implementation Specifications โœจ

Default

WON'T DET -- DON'T DET

Neither host wishes to use the Data Entry Terminal option ๐Ÿ™…โ€โ™€๏ธ

Minimal Implementation

DET EDIT FACILITIES
DET ERASE FACILITIES
DET TRANSMIT FACILITIES
DET FORMAT FACILITIES
DET MOVE CURSOR <x><y>
DET HOME
DET ERASE SCREEN
DET TRANSMIT SCREEN
DET FORMAT DATA
DET ERROR <cmd> <error code>

In the case of formatting the data, the minimal implementation should be able to support a low and high level of intensity and protection for all or no characters in a field. These functions, however, are not required ๐ŸŒท

The minimal implementation also requires that the Output Line Width and Output Page Size Telnet options be supported ๐Ÿ“


4. Motivation ๐Ÿฆ‹

The Telnet protocol was originally designed to give scroll-mode terminals, like the standard teletype, a way to talk to processes over the network ๐Ÿ“Ÿ That was fine for the vast majority of terminals and users back then. But as the network spread into other areas, especially ones where it's treated as a production environment for other work, what users wanted and needed changed ๐Ÿ“ˆ So it became necessary to consider supporting facilities that weren't originally supported. This Telnet option tries to do that for applications that need data entry terminals ๐Ÿ’œ

This option effectively defines the Network Virtual Data Entry Terminal ๐Ÿงš The description is quite long, but that doesn't mean Telnet is a bad vehicle for this facility. Data Entry Terminals are rather complex and varied in what they can do ๐ŸŒˆ This option tries to support both the minimal set of useful functions that are either common to all of them or easy to simulate, and the more sophisticated functions that some terminals provide ๐Ÿ‘‘

Unlike most real data entry terminals, where the terminal functions are encoded into one or more characters of the native character set, this option does all of those controls inside the Telnet subnegotiation mechanism ๐ŸŽ€ That lets programs that are intimately familiar with the kind of terminal they're talking to send commands that the option or the implementation might not support. In other words, you can operate in a "raw" or at least "rare" mode using as much of the option as you need ๐Ÿ”ฅ

Although many data entry terminals support a variety of peripheral devices such as printers, cassettes, and so on, it's beyond the scope of this option to deal with those ๐Ÿ–จ๏ธ A separate option should be defined to handle that aspect of these devices ๐Ÿซถ

5. Description โœจ

General Notes ๐ŸŽ€

okay bestie, every implementation of this option is required to support a certain minimal set of subcommands ๐Ÿ’…. Section 3 has the full list of what's in that set. Telnet's whole philosophy is that an implementation shouldn't have to parse commands it doesn't implement ๐Ÿซถ, so every subcommand here is either in the minimal set or covered by one of the facility subcommands. An implementation must "negotiate" with its correspondent for permission before using any subcommand outside the minimal set ๐Ÿ”ฅ. The details of that process are in the facility subcommands section below.

Most data entry terminals run in half duplex mode ๐Ÿ“. (Lots of DETs on the market can also work as standard interactive terminals, but we're only talking about them as DETs here ๐Ÿ™ˆ.) When this option is in use, it's suggested that the Echo, Remote Controlled Transmission and Echoing, and Suppress Go-Ahead options get refused. BUT this option could also support a simple full duplex CRT app using the basic cursor control functions here ๐Ÿ’ป. For those cases, one or more of those options might be required. (Fancy interactive calligraphic apps are beyond this option's scope and should be handled by another option or the Network Graphics Protocol ๐Ÿ’œ.)

Now for the synch drama ๐Ÿ˜ญ. RFC 728 pointed out that a synch sequence can cause messy interactions between Telnet Control functions and the data stream. A synch sequence flushes data but not control functions. So if a control function that affects the data right after it is sitting in the stream when a synch happens, it won't hit the data it was meant for. It'll land on whatever comes after the Data Mark instead ๐Ÿ™ƒ. These DET subcommands are vulnerable to this pitfall:

  • CHAR INSERT
  • DATA TRANSMIT
  • FORMAT DATA

The fix is for the receiver of the synch sequence to delete these subcommands, plus all the data attached to them, before processing the control functions ๐Ÿงน. That also means the Data Mark should not occur in the middle of the data for these subcommands.


Facility Subcommands ๐Ÿฆ‹

These four subcommands are how the User and Server implementations negotiate which subcommands and attributes of the terminal can be used ๐Ÿค. Picture it like this: the terminal (User Host) says what facilities it has, and the Server Host (or application program) says what facilities it wants ๐Ÿ‘‘.

When Sent: A Server Telnet implementation using the DET option must send a facility subcommand asking to use a particular subcommand or terminal attribute that isn't in the minimal implementation, and it has to do this before the first use of that subcommand or attribute ๐Ÿ“จ. The User Telnet implementation should reply as fast as it can โšก. Neither the User nor the Server is required to negotiate one subcommand at a time, so you can batch ๐Ÿ’–. A Telnet implementation answering a facility subcommand doesn't have to only approve that one thing either. It can send a format map listing every facility in that class it supports ๐Ÿ—บ๏ธ. Also, a Telnet implementation that's requesting facilities must send a facility subcommand before its first use of the subcommand, even if earlier negotiations already showed the facility is provided ๐Ÿ™ˆ. The facility can't be used until a matching facility subcommand has come back. Other than that, there are no constraints on when facility subcommands can be sent. Honestly, the app doesn't have to know every facility it'll use at the start of a session ๐ŸŒธ.

Action When Recieved: There are two possible actions when a facility subcommand comes in, depending on whether the receiver is a requestor or a provider (User) ๐ŸŽญ.

  • Requestor: When a requestor gets a facility subcommand while it's in the state of Waiting for a Reply, it should move into the state of Not Waiting โœ…. Then it takes the facility map it sent and forms the logical intersection with the facility map it received. (For the Intensity attribute, take the minimum of the number received and the number requested ๐Ÿ”ข.) The result is the set of facilities that were successfully negotiated ๐ŸŽ‰. Note: if the receiver isn't in the Waiting for Reply state, then this is the provider case we're about to get into.
  • Provider: When a facility subcommand comes in, the provider should send a facility subcommand with a facility map of the facilities it provides as soon as possible ๐Ÿš€. Then it figures out which new facilities it's providing for the Requestor by forming the logical intersection of the facility map it received and the one it sent ๐Ÿ’….

Note: In most cases the requestor is the Server Host and the provider is the User Host that supports the terminal, but that split isn't always the case ๐ŸŒˆ.


Transmit Subcommands ๐Ÿ“ก

There are two kinds of transmit subcommands ๐Ÿ’ซ. One kind is for requesting that data be sent to the requestor, and the other prefaces data that's sent to the requestor. The first kind lets the requestor control when data is transmitted, where it comes from on the terminal, and to some extent how much gets sent ๐ŸŽ›๏ธ. That one's pretty straightforward, and you can find it in Section 2 ๐Ÿง.

Data can leave the terminal for two reasons: the terminal user caused the transmission, or it was a response to a transmit subcommand ๐Ÿ“ค. Some programs want to know where on the screen the transmission started ๐Ÿ“. (That's totally reasonable, because the user might have moved the cursor all over the place before hitting transmit ๐Ÿ™ˆ.) Other programs don't need that info, and that's fine too. The DATA TRANSMIT subcommand exists for the programs that do need it ๐Ÿงš. When it's used, it prefaces the data coming from the terminal. The parameters <x> and <y> give the screen coordinates of where the transmission begins. <x> must be less than or equal to M-1, and <y> must be less than or equal to N-1 ๐Ÿ“. Everything between this DATA TRANSMIT and the next one is assumed to start at the coordinates from the first subcommand, then keep filling each line after that according to the screen's constraints and the format effectors in the data ๐Ÿ“. So an intelligent (or sloppy, depending on your point of view ๐Ÿ˜Œ) user-host DET implementation only needs to include a DATA TRANSMIT when the new starting point is different from the last ending point ๐Ÿ’–.

6. Sample Interaction ๐ŸŽ€

okay so bestie, this section is the vibe check ๐Ÿ’… It's a full example, and RFC 726 gets to be the boss of the notation here. Here's the cheat sheet:

  • S: means the serving host is sending it to the using host ๐Ÿ“ค
  • U: means the using host is sending it to the serving host ๐Ÿ“ฅ
  • T: means the terminal user typed it โŒจ๏ธ
  • P: means it got printed on the terminal ๐Ÿ–จ๏ธ

Square brackets [] are just commentary (like a little aside ๐Ÿ™ˆ), and angle brackets <> mean the thing inside is one single unit. So carriage return is <cr>, and decimal 27 is written <27>. Easy peasy ๐ŸŒธ

We're assuming the user already set up the Telnet connection, logged on, and an application just started up, either by hand or through a canned startup procedure โœจ Also, the layout on the page is only there to group things together. It does NOT tell you where the message boundaries are, so assume any bit of the dialogue could be sent as one message or as a whole bunch of them ๐Ÿงš The very first move from the program (or Telnet) is negotiating the DET option:

S: <IAC><DO><DET>

U: <IAC><WILL><DET>

S:<IAC><DO><OUTPUT PAGE SIZE>              [First negotiate the screen
                                           size.  In this case we are
                                           asking the user the size of
                                           the terminal.  This could
                                           have been done before the
                                           DET option was negotiated.]

U:<IAC><WILL><NAOP>

U:<IAC><SB><NAOP><DR><25><IAC><SE>

S:<IAC><SB><NAOP><DS><0><IAC><SE>

S:<IAC><DO><OUTPUT LINE WIDTH>
U:<IAC><SB><NAOL><DR><80><IAC><SE>         [Defines the screen to be
                                           25 lines by 80 characters.
                                           The server may use this
                                           information when formatting
                                           the screen.]

S:<IAC><SB><NAOL><DS><0><IAC><SE>

S:<IAC><SB><DET><FORMAT FACILITIES>
<Repeat><Protection, 3 Levels
Intensity><IAC><SE>                        [Now set the terminal
                                           attributes.]

U:<IAC><SB><DET><FORMAT FACILITIES>
<Repeat, Blinking><Protection, 3
Levels Intensity><IAC><SE>

S:<IAC><SB><DET><ERASE SCREEN><IAC><SE>    [Erase the screen and start
                                           sending the form.]

  <IAC><SB><DET><FORMAT DATA>
  <Protection=1, Intensity=1><0>
  <5><IAC><SE>Name:

  <IAC><SB><DET><MOVE CURSOR><0><1><IAC><SE>

  <IAC><SB><DET><FORMAT DATA>
  <Protection=1, Intensity=1><0>
  <8><IAC><SE>Address:

  <IAC><SB><MOVE CURSOR><0><4><IAC><SE>

  <IAC><SB><DET><FORMAT DATA>
  <Protection=1, Intensity=1><0>
  <17><IAC><SE>Telephone number:

  <IAC><SB><DET><MOVE CURSOR><32><4><IAC><SE>

  <IAC><SB><DET><FORMAT DATA>
  <Protection=1, Intensity=1><0>
  <24><IAC><SE>Social Security Number:

  <IAC><SB><DET><FORMAT DATA>
  <Protection=1, Intensity=7>
  <0><11><IAC><SE>                         [Establish a field that
                                           doesn't display what is
                                           typed into it.]

  <IAC><SB><DET><MOVE CURSOR><32><5><IAC><SE>

  <IAC><SB><DET><FORMAT FACILITIES>
  <Blinking><0><IAC><SE>                   [Get permission to use
                                           Blinking Attribute.]

U:<IAC><SB><DET><FORMAT FACILITIES>
<Repeat, Blinking><Protection,
3 Levels Intensity><IAC><SE>

S:<IAC><SB><DET><FORMAT DATA>
<Blinking=1, Protection=1,
Intensity=1><0><29><IAC><SE>

  Your SSN will not be printed.

  <IAC><SB><DET><HOME><IAC><SE>
  <IAC><GA>

Okay, so that whole exchange just set up a form on the screen, and it looks like this, with the quoted string blinking โœจ๐Ÿฆ‹

Name:
Address:
Telephone Number:                       Social Security Number:
                                   "Your SSN will not be printed."

Now the terminal user is free to fill in the form ๐Ÿ’– They put the cursor at the start of the first field (usually by hitting tab) and start typing. We don't show that part, because it doesn't talk to the User Telnet program or the network at all. Once they've finished, they hit the transmit key to send the unprotected part of the form. But FIRST, the User Telnet program negotiates the Byte Macro Option so the Field Separator subcommand can get condensed ๐Ÿ“

U:<IAC><DO><BM>                            [Negotiate Byte Macro
                                           Option.]

S:<IAC><WILL><BM>                          [Define decimal 166 to be
                                           the Field Separator
                                           subcommand (see Appendix
                                           3)]

U:<IAC><SB><BM><DEFINE>
<166><6><IAC SB DET FIELD
SEPARATOR IAC SE><IAC><SE>

S:<IAC><SB><BM><ACCEPT><166><IAC><SE>      [The server accepts the
                                           macro.]

U:<IAC><SB><DET><DATA TRANSMIT><0><6><IAC><SE>
John Doe <166> 1515 Elm St., Urbana, Il 61801
<166> 217-333-9999 <166> 123-45-6789 <166>

S:<IAC><SB><DET><ERASE SCREEN><IAC><SE>
Thank you.

And so on ๐ŸŒˆ๐Ÿ’…

Appendix 1 - Subcommands, opcodes and syntax ๐Ÿงš

Here's the full subcommand menu, with the opcode and the syntax for each one ๐Ÿ“‹

1         EDIT FACILITIES      <Facilty map>
2         ERASE FACILITIES     <Facility map>
3         TRANSMIT FACILITIES  <Facility map>
4         FORMAT FACILITIES    <Facility map 1> <Facility map 2>
5         MOVE CURSOR          <x> <y>
6         SKIP TO LINE         <y>
7         SKIP TO CHAR         <x>
8         UP
9         DOWN
10        LEFT
11        RIGHT
12        HOME
13        LINE INSERT
14        LINE DELETE
15        CHAR INSERT
16        CHAR DELETE
17        READ CURSOR
18        CURSOR POSITION      <x><y>
19        REVERSE TAB
20        TRANSMIT SCREEN
21        TRANSMIT UNPROTECTED
22        TRANSMIT LINE
23        TRANSMIT FIELD
24        TRANSMIT REST OF SCREEN
25        TRANSMIT REST OF LINE
26        TRANSMIT REST OF FIELD
27        TRANSMIT MODIFIED
28        DATA TRANSMIT <x><y>
29        ERASE SCREEN
30        ERASE LINE
31        ERASE FIELD
32        ERASE REST OF SCREEN
33        ERASE REST OF LINE
34        ERASE REST OF FIELD
35        ERASE UNPROTECTED
36        FORMAT DATA <format map>
37        REPEAT     <count><char>
38        SUPPRESS PROTECTION <negotiation>
39        FIELD SEPARATOR
40        FN <code>
41        ERROR  <cmd><error code>

Appendix 2 - Error Codes ๐Ÿšจ

Things can go sideways, so here's the list of error codes ๐Ÿ™ˆ

1         Facility not previously negotiated.

2         Illegal subcommand code.

3         Cursor Address Out of Bounds.

4         Undefined FN value.

5         Can't negotiate acceptable line width.

6         Can't negotiate acceptable page length.

7         Illegal parameter in subcommand.

8         Syntax error in parsing subcommand.

9         Too many parameters in subcommand.

10        Too few parameters in subcommand.

11        Undefined parameter value

12        Unsupported combination of Format Attributes

Appendix 3 - Use of the Byte Macro Option ๐Ÿ‘‘

Okay, so the big downside of DET is the overhead ๐Ÿ˜ญ Because the functions are encoded as Telnet option subnegotiations, each one costs a lot of bytes. Something like Character Insert is a single byte on most terminals, but in DET it takes six. The only other way to get the same transparency that subcommands give you would've been to define extra Telnet control functions, but that means changing Telnet itself, and people felt that was not a wise move. Then the Telnet Byte Macro Option (RFC 729) came along ๐ŸŽ‰ It lets the user and server Telnets map an arbitrary character string onto a single byte that gets sent over the net. So the Byte Macro Option gives implementations a way to skip the overhead for the subcommands they use a lot. The rest of this appendix suggests how to apply the Byte Macro Option to the DET option โœจ

Following the Byte Macro Option spec, macro bytes come from the range 128 to 239. For DET, the suggestion is to pick the macro byte by adding the subcommand code to 128. There's also an unofficial DET subcommand that could be defined to say each side is willing to support macro bytes for all subcommands (but not necessarily support the subcommands themselves) using this algorithm. That subcommand would look like this:

IAC SB DET DET-MACRO <negotiation> IAC SE       subcommand code: 254

Here, <negotiation> can take the values of the Telnet option negotiation:

251     WILL
252     WONT
253     DO
254     DONT

A Telnet implementation sends this subcommand to show it's willing to adopt byte macros for all of the DET subcommands, following this algorithm ๐Ÿฆ‹

The macro byte for subcommand i will be i+128 and will represent the
following string for parameterless subcommands:

IAC SB DET <subcommand code> IAC SE

and the following string for subcommands with parameters:

IAC SB DET <subcommand code>

The default for this subcommand is that the macros are NOT in effect, so it's:

IAC SB DET DET-MACRO WONT IAC SE
IAC SB DET DET-MACRO DONT IAC SE

Negotiating this subcommand works the same way as negotiating any other Telnet option ๐Ÿ’œ

References ๐Ÿ“š

  1. ADM-1 Interactive Display Terminal Operator's Handbook Lear-Siegler, Inc. 7410-31.
  2. ADM-Interactive Display Terminal Operator's Handbook Lear-Siegler, Inc. EID, 1974.
  3. Burroughs TD 700/800 Reference Manual, Burroughs Corp., 1973
  4. Burroughs TD 820 Reference Manual, Burroughs Corp. 1975.
  5. CC-40 Communications Station: General Information Manual. Computer Communication, Inc. Pub. No. MI-1100. 1974.
  6. Crocker, David. "Telnet Byte Macro Option," RFC 729, 1977.
  7. Data Entry Virtual Terminal Protocol for Euronet, DRAFT, 1977.
  8. Day, John. "A Minor Pitfall in the Telnet Protocol," RFC 728, 1977.
  9. Hazeltine 2000 Desk Top Display Operating Instructions. Hazeltine IB-1866A, 1870.
  10. How to Use the Consul 980: A Terminal Operator's Guide and Interface Manual. Applied Digital Data Systems, Inc. 98-3000.
  11. How to Use the Consul 520: A Terminal Operator's Guide and Interface Manual. Applied Digital Data Systems, Inc. 52-3000.
  12. Honeywell 7700 Series Visual Information Projection (VIP) Systems: Preliminary Edition. 1973.
  13. An Introduction to the IBM 3270 Information Display System. IBM GA27-2739-4. 1973.
  14. Naffah, N. "Protocole Appareil Virtuel type Ecran" Reseau Cyclades. TER 536. 1976.
  15. Postel, Jon and Crocker, David. "Remote Controlled Transmission and Echoing Telnet Option", RFC 726 NIC 39237, Mar. 1977.
  16. Schicker, Peter. "Virtual Terminal Protocol (Proposal 2). INWG Protocol Note #32., 1976.
  17. UNISCOPE Display Terminal : Programmer Reference . Sperry- Univac UP-7807 Rev. 2, 1975.
  18. Universal Terminal System 400: System Description. Sperry- Univac UP-8357, 1976.
  19. Walden, David C. "Telnet Output Line Width Option." NIC # 20196, 1973, also in ARPANET Protocol Handbook, 1976.
  20. Walden, David C. "Telnet Output Page Size" NIC # 20197, 1973, also in ARPANET Protocol Handbook, 1976.
๐Ÿ“ฆ where this page comes from