Commands and option negotiation
Subnegotiation and terminal details
Follow option-specific data between IAC SB and IAC SE, including terminal type and window dimensions.
8 minute lesson
WILL and DO can only say yes or no. That is enough for a switch like ECHO, but some options need more information after WILL and DO agree that the option may be used. “What terminal type are you?” cannot be answered with a yes. Telnet carries that data inside subnegotiation.
A subnegotiation begins with IAC SB, includes the option code and its data, then ends with IAC SE:
IAC SB option ...data... IAC SE
255 250 option ...data... 255 240
SB is byte 250 and SE is byte 240. Everything between them belongs to the named option and follows that option’s own rules, defined in its own RFC.
NAWS: window size
The NAWS option, code 31, lets a client report its window width and height:
IAC SB NAWS 0 80 0 24 IAC SE
This example reports an 80-column, 24-row window. Each dimension uses two bytes in network byte order, so 80 is 0 80 and a width of 300 would be 1 44 (256 + 44). The server uses this to format output, and a good client sends a fresh NAWS subnegotiation whenever you resize the window.
TERMINAL-TYPE: a two-step dialogue
The TERMINAL-TYPE option, code 24, lets a server request a terminal name. After the client agrees with WILL TERMINAL-TYPE, the server asks and the client answers:
server: IAC SB TERMINAL-TYPE 1 IAC SE (1 = SEND)
client: IAC SB TERMINAL-TYPE 0 x t e r m IAC SE (0 = IS)
The name travels as plain ASCII characters inside the subnegotiation. Notice the pattern: negotiation decided whether to exchange terminal types, and subnegotiation carries what the type is.
The escaping rule still applies
Any data byte equal to 255 must still be doubled, even inside a subnegotiation. Otherwise a receiver could mistake it for the IAC that starts IAC SE.
This matters for NAWS specifically. A window 255 columns wide has a dimension byte of 255, so the client must send it twice. A parser that forgets this rule ends the subnegotiation early and misreads everything after it. If you ever write a Telnet parser, this is the test case to write first.
Lesson completed