blob: f00aba9f0992d2b1dbad856010c5c9fe294c853c [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001CONCEPT
2 Telnet Negotiations
3
4DESCRIPTION
5 The telnet protocol is used to control textbased connections
6 between a client (the 'telnet' program or a mud client) and a
7 server (the game driver). Most of the options offered by the
8 protocol are optional and need to be negotiated between the
Zesstra7ea4a032019-11-26 20:11:40 +01009 client and the server. Consequently, and due to their
MG Mud User88f12472016-06-24 23:31:02 +020010 specialized nature, mud clients don't have to support the full
11 telnet option feature set.
12
13 For the server to find out if a client supports the telnet
Zesstra7ea4a032019-11-26 20:11:40 +010014 protocol at all, one good approach is to issue a simple,
15 commonly used telnet command to the client. If the client reaction
16 conforms to the protocol (or sends telnet commands itself), the
MG Mud User88f12472016-06-24 23:31:02 +020017 mud can continue to negotiate further options. If the client
18 does not react, the mud can safely refrain from further
19 negotiations.
20
21 The following list is a more or less comprehensive overview of
22 the telnet related RFCs (available for example on
23 http://www.faqs.org/rfcs):
24
Zesstra7ea4a032019-11-26 20:11:40 +010025 RFC Title rel. Code
MG Mud User88f12472016-06-24 23:31:02 +020026
Zesstra7ea4a032019-11-26 20:11:40 +010027 495 TELNET Protocol Specification
28 513 Comments on the new TELNET specifications
29 559 Comments on the new TELNET Protocol and its Implem
30 595 Some Thoughts in Defense of the TELNET Go-Ahead
31 596 Second Thoughts on Telnet Go-Ahead
32 652 Telnet Output Carriage-Return Disposition Option NAOCRD 10
33 653 Telnet Output Horizontal Tabstops Option NAOHTS 11
34 654 Telnet Output Horizontal Tab Disposition Option NAOHTD 12
35 655 Telnet Output Formfeed Disposition Option NAOFFD 13
36 656 Telnet Output Vertical Tabstops Option NAOVTS 14
37 657 Telnet Output Vertical Tab Disposition Option NAOVTD 15
38 658 Telnet Output Linefeed Disposition NAOLFD 16
39 698 Telnet Extended Ascii Option X-ASCII 17
40 727 Telnet Logout Option LOGOUT 18
41 728 A Minor Pitfall in the Telnet Protocol
42 735 Revised TELNET Byte Macro Option BM 19
43 749 Telnet SUPDUP-OUTPUT Option SUPDUP 22
44 764 Telnet Protocol Specification
45 779 Telnet SEND-LOCATION Option SENDLOC 23
46 818 The Remote User Telnet Service
47 854 Telnet Protocol Specification
48 855 Telnet Option Specifications
49 856 Telnet Binary Transmission BINARY 0
50 857 Telnet Echo Option ECHO 1
51 858 Telnet Suppress Go Ahead Option SGA 3
52 859 Telnet Status Option STATUS 5
53 860 Telnet Timing Mark Option TM 6
54 861 Telnet Extended Options - List Option EXOPL 255
55 884 Telnet Terminal Type Option TTYPE 24
56 885 Telnet End of Record Option EOR 25
57 930 Telnet Terminal Type Option TTYPE 24
58 933 Output Marking Telnet Option OUTMRK 27
59 946 Telnet Terminal Location Number Option TTYLOC 28
60 1043 Telnet Data Entry Terminal Option DODIIS Implement DET 20
61 1053 Telnet X.3 PAD Option X.3-PAD 30
62 1073 Telnet Window Size Option NAWS 31
63 1079 Telnet Terminal Speed Option TSPEED 32
64 1080 Telnet Remote Flow Control Option FLOWCTRL 33
65 1091 Telnet Terminal-Type Option TTYPE 24
66 1096 Telnet X Display Location Option XDISPLOC 35
67 1116 Telnet Linemode Option LINEMODE 34
68 1143 The Q Method of Implementing TELNET Option Negotia
69 1184 Telnet Linemode Option LINEMODE 34
70 1372 Telnet Remote Flow Control Option FLOWCTRL 33
71 1408 Telnet Environment Option ENVIRON 36
72 1571 Telnet Environment Option Interoperability Issues
73 1572 Telnet Environment Option NEWENV 39
74 2066 Telnet Charset Option CHARSET 42
75 2217 Telnet Com Port Control Option COMPORT 44
76 2877 5250 Telnet Enhancements
MG Mud User88f12472016-06-24 23:31:02 +020077
78 All negotiations start with the special character IAC which is
79 defined in /usr/include/arpa/telnet.h (or in
80 src/driver/telnet.h for 3.2(.1)) and has the decimal value of
81 255. Negotiations are based on different telnetoptions (their
82 values are defined in telnet.h too). Before a negotiation can
83 start the client and the server have to agree that they
Zesstra7ea4a032019-11-26 20:11:40 +010084 support the option. This works in the following way:
MG Mud User88f12472016-06-24 23:31:02 +020085
86 If a client wants to send something to the server it has to
87 send 'IAC WILL option' (For terminaltype negotation this would
88 be the 3 bytes 255,251,24; again, check telnet.h) to confirm
89 that it is able to do that. If the server is supporting that
90 option and wants to receive something it sends 'IAC DO option'
91 (255,253,option)
92
93 If one side is receiving an 'IAC WILL option' and has not yet
94 sent with DO or DONT it has to respond with either 'IAC DO
95 option' if it will support this negotiation or 'IAC DONT
96 option' if it won't.
97
98 If one side is receiving an 'IAC DO option' and has not yet
99 sent a WILL or WONT it has to reply with either 'IAC WILL
100 option' if it supports the option or 'IAC WONT option' if not.
101
Zesstra7ea4a032019-11-26 20:11:40 +0100102 A small example: Lets assume we want to negotiate
MG Mud User88f12472016-06-24 23:31:02 +0200103 terminaltype. (TELOPT_TTYPE with value 24). client is the
104 telnet executable on the playerside, the server is the
105 gamedriver.
106
107 client server
108 IAC WILL TTYPE
Zesstra7ea4a032019-11-26 20:11:40 +0100109 IAC DO TTYPE
MG Mud User88f12472016-06-24 23:31:02 +0200110
111 Or:
Zesstra7ea4a032019-11-26 20:11:40 +0100112 IAC DO TTYPE
MG Mud User88f12472016-06-24 23:31:02 +0200113 IAC WILL TTYPE
114
115 After this we are ready to transfer the terminaltype from the
116 client to the server as explained below.
117
118 Now we are ready to start the real negotiations. I explain the
119 3 options I have currently implemented.
120
121 First TerminalType aka TTYPE aka 24 aka TELOPT_TTYPE assuming
122 the client and the server have exchanged WILL/DO.
123
124 The server is now free to send 'IAC SB TELOPT_TTYPE
125 TELQUAL_SEND IAC SE' which will be replied with 'IAC SB
126 TELOPT_TTYPE TELQUAL_IS terminaltype IAC SE' where
127 terminaltype is a non-zero terminated string (it's terminated
128 by the IAC) (For values look up telnet.h) AND switch the
129 client's terminalemulation to 'terminaltype'. terminaltype is
130 case-insensitive. terminal-type may be UNKNOWN. The server may
131 repeat the SEND request and the client will respond with the
132 next preferred terminaltype. If this is the same as the
133 previous received, it marks the end of the list of
134 terminaltypes. The next SEND request will start the
135 terminaltypes from the beginning.
136
137 Example: (we have exchanged WILL/DO already)
138 client server
Zesstra7ea4a032019-11-26 20:11:40 +0100139 IAC SB TTYPE SEND IAC SE
MG Mud User88f12472016-06-24 23:31:02 +0200140 IAC SB TTYPE IS VT200 IAC SE
Zesstra7ea4a032019-11-26 20:11:40 +0100141 IAC SB TTYPE SEND IAC SE
MG Mud User88f12472016-06-24 23:31:02 +0200142 IAC SB TTYPE IS VT100 IAC SE
Zesstra7ea4a032019-11-26 20:11:40 +0100143 IAC SB TTYPE SEND IAC SE
MG Mud User88f12472016-06-24 23:31:02 +0200144 IAC SB TTYPE IS VT52 IAC SE
Zesstra7ea4a032019-11-26 20:11:40 +0100145 IAC SB TTYPE SEND IAC SE
MG Mud User88f12472016-06-24 23:31:02 +0200146 IAC SB TTYPE IS VT52 IAC SE
147 /* this marks that we have all terminaltypes. We decide to use the
148 * vt200 mode so we have to skip to VT200
149 */
Zesstra7ea4a032019-11-26 20:11:40 +0100150 IAC SB TTYPE SEND IAC SE
MG Mud User88f12472016-06-24 23:31:02 +0200151 IAC SB TTYPE IS VT200 IAC SE
152
153
154 Next important option is NAWS (31) or WindowSizeNegotiation.
155
156 This one is a bit easier than terminaltype. After having
157 received a IAC DO NAWS from the server, the client will reply
158 with IAC WILL NAWS and immediately after that send IAC SB NAWS
159 columns_high columns_low lines_high lines_low IAC SE where
160 xx_low refers to the lowbyte of xx and xx_high refers to the
161 highbyte of xx. This will be automagically resent at every
162 windowresize (when the client gets a SIGWINCH for example) or
163 at your request with 'IAC SB NAWS SEND IAC SE'.
164
165 Example: (WILL/DO exchanged)
166 client server
167 IAC SB NAWS 0 80 0 24 IAC SE /* the standard vt100 windowsize */
Zesstra7ea4a032019-11-26 20:11:40 +0100168 /* no reply */
MG Mud User88f12472016-06-24 23:31:02 +0200169
170 And, a bit less important but most complex, the LINEMODE (34)
171 option. It was implemented it due to the fact, that
172 some weird DOS telnets would not work otherwise. Implemented
173 are only the absolute basic feature, which is the actual
174 switching the telnet to linemode. After exchanging WILL/DO the
175 server sends a modechange request to the client using IAC SB
176 LINEMODE LM_MODE MODE_EDIT IAC SE, which should turn on local
177 commandline-editing for the client. If a client supports
178 LINEMODE it HAS to support this modechange. The client will
179 reply with IAC SB LINEMODE LM_MODE MODE_EDIT|MODE_ACK IAC SE
Zesstra7ea4a032019-11-26 20:11:40 +0100180 (x|y is bitwise or). That's it for linemode. (You will perhaps
MG Mud User88f12472016-06-24 23:31:02 +0200181 receive other IAC SB LINEMODEs with other LM_xxx ... you may
182 ignore them. (At least IRIX 5.x sends IAC SB LINEMODE LM_SLC
183 .... IAC SE which declares the local characterset.)).
184
185 Example: (WILL/DO negotiated)
186
187 client server
188 IAC SB LINEMODE LM_MODE
189 MODE_EDIT IAC SE
190 IAC SB LINEMODE LM_MODE
191 MODE_EDIT|MODE_ACK IAC SE
192
Zesstra7ea4a032019-11-26 20:11:40 +0100193 Note: The option is more interesting than it looks here. For
194 example it supports a mixed mode between linemode and
195 charactermode, flushing the input at certain characters (at
MG Mud User88f12472016-06-24 23:31:02 +0200196 ESC or TAB for shell-like commandline completition). We suggest
197 reading RFC 1184.
198
199 You might be interested in TELOPT_XDISPLAYLOC and TELOPT_ENVIRON too.
200
201 Now, how to implement this using LDMud?
202
203 0. Patch src/driver/comm1.c, function init_telopts() to include
204 telopts_do[TELOPT_XXX] = reply_h_telnet_neg;
205 telopts_dont[TELOPT_XXX] = reply_h_telnet_neg;
206 telopts_will[TELOPT_XXX] = reply_h_telnet_neg;
207 telopts_wont[TELOPT_XXX] = reply_h_telnet_neg;
208 for every telnet negotiation you want to use.
209 Do not overwrite the TELOPT_ECHO and TELOPT_SGA hooks.
210
211 Alternatively, set the driver hook H_NOECHO in master.c:
212 this diverts _all_ telnet data into the mudlib.
213
214 1. Add a new driver hook to master.c just below the others.
215 set_driver_hook(H_TELNET_NEG,"telnet_neg"),
216 2. Make a telnet.h for your mudlib... just change the arrays in
217 src/driver/telnet.h.
218 3. define a function
219
220 void telnet_neg(int cmd, int option, int * optargs)
221
222 in your interactive objects (login.c , shells, player.c or
223 whereever). And note, in ALL objects, through which a
224 player is handed through (in TAPPMud these are login.c and
225 player.c). [Ok, master.c is interactive for a very short
226 time too, but it won't accept input, will it?]
227 'cmd' will be TELCMD_xxxx (see telnet.h), 'option' one of
228 TELOPT_xxxx and 'optargs' will be an array of ints (bytes in
229 fact) when 'cmd' is SB.
230 Parse 'cmd'/'option' and reply with appropiate answers
231 using binary_message() (appropiate meaning sending the
232 right DO/DONT/WILL/WONT if not sent before and using the SB
233 return values).
Zesstra7ea4a032019-11-26 20:11:40 +0100234 3.1. Send IAC DO TTYPE IAC DO NAWS IAC DO LINEMODE at the
MG Mud User88f12472016-06-24 23:31:02 +0200235 first time you can do it (before cat()ing /WELCOME perhaps).
236 3.2. Note all sent and received WILL/WONT/DO/DONT options for
237 conforming to the standard, avoiding endless loops and for
238 easy debugging :)
239 3.3. Pass those recevied/sent data and other data when the
240 interactive object is changed (from login.c to player.c or
241 at other bodychanges). Clear the data when the player goes
242 linkdead or quits. You won't need to save this data.
243 3.4. Lower_case() terminaltypes... ;)
244 3.5. Use reasonable defaultvalues if the client does not
Zesstra7ea4a032019-11-26 20:11:40 +0100245 support one of the options. (columns 80, lines 24 if not
MG Mud User88f12472016-06-24 23:31:02 +0200246 NAWS, unknown or vt100 for no terminaltype)
247
248 The WILL/WONT/DO/DONT data is best saved in a mapping looking
249 like this:
250 ([ "received": ([ option1: DO_DONT_OR_0;WILL_WONT_OR_0, ... ])
251 , "sent" : ([ option1: DO_DONT_OR_0;WILL_WONT_OR_0, ... ])
252 ])
253
254 (Ok, it can be done better. But not without confusing *me*
255 more.)
256
257 Before sending anything check
258 TN["sent"][option,0_if_do_dont_or_1_if_will_wont]
259 so you don't enter endless loops, save network traffic and the
260 like.
261
262 The windowsize is best saved in the players environment
263 variables so that he can modify them later on. (Or in two
264 integers in the player object...). Use for these values is
265 clear I think.
266
267 The terminaltypes received using above mentioned method are
268 best stored in an array. The actual set terminaltype is best
269 stored in an environment variable where the player can modify
270 it. Upon modifying it the IAC SB TTYPE SEND IAC SE cycle
271 should be started to match the emulation to the entered new
272 terminaltype. You then may use data retrieved from
273 /etc/termcap (man 5 termcap) or /usr/lib/terminfo/*/* (SysVID,
274 man 5 terminfo) to implement terminalcontrol codes dependend
275 on the terminaltype. /etc/termcap may prove to be the easiest
276 way tough /usr/lib/terminfo/*/* is the newer (and better) SysV
277 way of doing it.
278
279 [Anyone got a description of the internal terminfo format for
280 me? -Marcus]
281
282 LINEMODE replies may be left alone if only using the mode
283 change to MODE_EDIT
284
285 Some statistics about what clients support telnet negotiations:
286
287 Tinyfugue and some other mudclients usually do not support
288 negotiations.
Zesstra7ea4a032019-11-26 20:11:40 +0100289
MG Mud User88f12472016-06-24 23:31:02 +0200290 Except for TF, which supports the Telnet End-Of-Record option
291 as marker for the end of the prompt. So if you send IAC EOR
292 after every prompt, it will print the prompt always in the
293 input window. (Do not forget to negotiate that. First IAC WILL
294 TELOPT_EOR/wait for IAC DO TELOPT_EOR). Newer versions of
295 TF will support NAWS and there will be a patch for TTYPE
296 negotiation available soon.
297
298 All telnets able to do negotiations I've encountered support
299 the TTYPE option.
300 HP9.x,Irix5.x,Linux,EP/IX,CUTELNET/NCSATELNET (Novell) and
301 perhaps more support NAWS.
302 At least Irix5.x,Linux,CU/NCSATELNET support LINEMODE.
303 SUN does not support NAWS and LINEMODE neither in SunOS 4.1.3
304 nor in Solaris 2.3.
305
306 For getting RFCs you can for example use
307 ftp://ftp.uni-erlangen.de/pub/doc/rfc/
308
MG Mud User88f12472016-06-24 23:31:02 +0200309BUGS
310 Not all aspects of the options are mentioned to keep this doc
311 at a reasonable size. Refer to the RFCs to get more confused.
312
313CREDITS
314 Provided by Marcus@TAPPMud (Marcus Meissner,
315 <msmeissn@cip.informatik.uni-erlangen.de>).