Commands and option negotiation
Subnegotiation and terminal details
Follow option-specific data between IAC SB and IAC SE, including terminal type and window dimensions.
WILL and DO can only say yes or no. That is enough for a switch like ECHO. But some options need real data after both sides agree the option may be used. “What terminal type are you?” cannot be answered with a yes. Telnet carries that data inside a 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. The core Telnet parser only needs to find the start and the end. It hands the middle to whoever handles that option.
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 reports an 80-column, 24-row window. Each dimension uses two bytes in network byte order, most significant byte first. So 80 is 0 80, and a width of 300 would be 1 44, because 256 + 44 = 300.
The server uses this to format output. A good client sends a fresh NAWS subnegotiation every time you resize the window, and you will watch that happen live in the lab module.
TERMINAL-TYPE: a two-step dialogue
The TERMINAL-TYPE option, code 24, lets a server ask for 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 here. Negotiation decided whether to exchange terminal types. Subnegotiation carries what the type is. Two layers, two jobs.
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 and cut the subnegotiation short.
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 as terminal data.
If you ever write a Telnet parser, this is the test case to write first. It is the one every hand-rolled parser gets wrong, and it only shows up when someone’s terminal happens to be exactly 255 columns wide.
Lesson completed