blob: ed2318f083ccc1f1f63b831698a1479aabe68040 [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
9 client and the server. Consequently, and due to their
10 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
14 protocol at all, one good approach is to a simple, commonly
15 used telnet command to the client. If the client reacts
16 conform to the protocol (or sends telnet commands itself), the
17 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
25 RFC Titel rel. Code
26
27 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
77
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
84 support the option.
85 This works in the following way:
86
87 If a client wants to send something to the server it has to
88 send 'IAC WILL option' (For terminaltype negotation this would
89 be the 3 bytes 255,251,24; again, check telnet.h) to confirm
90 that it is able to do that. If the server is supporting that
91 option and wants to receive something it sends 'IAC DO option'
92 (255,253,option)
93
94 If one side is receiving an 'IAC WILL option' and has not yet
95 sent with DO or DONT it has to respond with either 'IAC DO
96 option' if it will support this negotiation or 'IAC DONT
97 option' if it won't.
98
99 If one side is receiving an 'IAC DO option' and has not yet
100 sent a WILL or WONT it has to reply with either 'IAC WILL
101 option' if it supports the option or 'IAC WONT option' if not.
102
103 A small example: Lets assume we want to negotiating
104 terminaltype. (TELOPT_TTYPE with value 24). client is the
105 telnet executable on the playerside, the server is the
106 gamedriver.
107
108 client server
109 IAC WILL TTYPE
110 IAC DO TTYPE
111
112 Or:
113 IAC DO TTYPE
114 IAC WILL TTYPE
115
116 After this we are ready to transfer the terminaltype from the
117 client to the server as explained below.
118
119 Now we are ready to start the real negotiations. I explain the
120 3 options I have currently implemented.
121
122 First TerminalType aka TTYPE aka 24 aka TELOPT_TTYPE assuming
123 the client and the server have exchanged WILL/DO.
124
125 The server is now free to send 'IAC SB TELOPT_TTYPE
126 TELQUAL_SEND IAC SE' which will be replied with 'IAC SB
127 TELOPT_TTYPE TELQUAL_IS terminaltype IAC SE' where
128 terminaltype is a non-zero terminated string (it's terminated
129 by the IAC) (For values look up telnet.h) AND switch the
130 client's terminalemulation to 'terminaltype'. terminaltype is
131 case-insensitive. terminal-type may be UNKNOWN. The server may
132 repeat the SEND request and the client will respond with the
133 next preferred terminaltype. If this is the same as the
134 previous received, it marks the end of the list of
135 terminaltypes. The next SEND request will start the
136 terminaltypes from the beginning.
137
138 Example: (we have exchanged WILL/DO already)
139 client server
140 IAC SB TTYPE SEND IAC SE
141 IAC SB TTYPE IS VT200 IAC SE
142 IAC SB TTYPE SEND IAC SE
143 IAC SB TTYPE IS VT100 IAC SE
144 IAC SB TTYPE SEND IAC SE
145 IAC SB TTYPE IS VT52 IAC SE
146 IAC SB TTYPE SEND IAC SE
147 IAC SB TTYPE IS VT52 IAC SE
148 /* this marks that we have all terminaltypes. We decide to use the
149 * vt200 mode so we have to skip to VT200
150 */
151 IAC SB TTYPE SEND IAC SE
152 IAC SB TTYPE IS VT200 IAC SE
153
154
155 Next important option is NAWS (31) or WindowSizeNegotiation.
156
157 This one is a bit easier than terminaltype. After having
158 received a IAC DO NAWS from the server, the client will reply
159 with IAC WILL NAWS and immediately after that send IAC SB NAWS
160 columns_high columns_low lines_high lines_low IAC SE where
161 xx_low refers to the lowbyte of xx and xx_high refers to the
162 highbyte of xx. This will be automagically resent at every
163 windowresize (when the client gets a SIGWINCH for example) or
164 at your request with 'IAC SB NAWS SEND IAC SE'.
165
166 Example: (WILL/DO exchanged)
167 client server
168 IAC SB NAWS 0 80 0 24 IAC SE /* the standard vt100 windowsize */
169 /* no reply */
170
171 And, a bit less important but most complex, the LINEMODE (34)
172 option. It was implemented it due to the fact, that
173 some weird DOS telnets would not work otherwise. Implemented
174 are only the absolute basic feature, which is the actual
175 switching the telnet to linemode. After exchanging WILL/DO the
176 server sends a modechange request to the client using IAC SB
177 LINEMODE LM_MODE MODE_EDIT IAC SE, which should turn on local
178 commandline-editing for the client. If a client supports
179 LINEMODE it HAS to support this modechange. The client will
180 reply with IAC SB LINEMODE LM_MODE MODE_EDIT|MODE_ACK IAC SE
181 (x|y is bitwise or). Thats it for linemode. (You will perhaps
182 receive other IAC SB LINEMODEs with other LM_xxx ... you may
183 ignore them. (At least IRIX 5.x sends IAC SB LINEMODE LM_SLC
184 .... IAC SE which declares the local characterset.)).
185
186 Example: (WILL/DO negotiated)
187
188 client server
189 IAC SB LINEMODE LM_MODE
190 MODE_EDIT IAC SE
191 IAC SB LINEMODE LM_MODE
192 MODE_EDIT|MODE_ACK IAC SE
193
194 Note: The option is much more funnier as it looks here, it for
195 example supports a mixed mode between linemode and
196 charactermode... flushing the input at certain characters (at
197 ESC or TAB for shell-like commandline completition). We suggest
198 reading RFC 1184.
199
200 You might be interested in TELOPT_XDISPLAYLOC and TELOPT_ENVIRON too.
201
202 Now, how to implement this using LDMud?
203
204 0. Patch src/driver/comm1.c, function init_telopts() to include
205 telopts_do[TELOPT_XXX] = reply_h_telnet_neg;
206 telopts_dont[TELOPT_XXX] = reply_h_telnet_neg;
207 telopts_will[TELOPT_XXX] = reply_h_telnet_neg;
208 telopts_wont[TELOPT_XXX] = reply_h_telnet_neg;
209 for every telnet negotiation you want to use.
210 Do not overwrite the TELOPT_ECHO and TELOPT_SGA hooks.
211
212 Alternatively, set the driver hook H_NOECHO in master.c:
213 this diverts _all_ telnet data into the mudlib.
214
215 1. Add a new driver hook to master.c just below the others.
216 set_driver_hook(H_TELNET_NEG,"telnet_neg"),
217 2. Make a telnet.h for your mudlib... just change the arrays in
218 src/driver/telnet.h.
219 3. define a function
220
221 void telnet_neg(int cmd, int option, int * optargs)
222
223 in your interactive objects (login.c , shells, player.c or
224 whereever). And note, in ALL objects, through which a
225 player is handed through (in TAPPMud these are login.c and
226 player.c). [Ok, master.c is interactive for a very short
227 time too, but it won't accept input, will it?]
228 'cmd' will be TELCMD_xxxx (see telnet.h), 'option' one of
229 TELOPT_xxxx and 'optargs' will be an array of ints (bytes in
230 fact) when 'cmd' is SB.
231 Parse 'cmd'/'option' and reply with appropiate answers
232 using binary_message() (appropiate meaning sending the
233 right DO/DONT/WILL/WONT if not sent before and using the SB
234 return values).
235 3.1. Sent IAC DO TTYPE IAC DO NAWS IAC DO LINEMODE at the
236 first time you can do it (before cat()ing /WELCOME perhaps).
237 3.2. Note all sent and received WILL/WONT/DO/DONT options for
238 conforming to the standard, avoiding endless loops and for
239 easy debugging :)
240 3.3. Pass those recevied/sent data and other data when the
241 interactive object is changed (from login.c to player.c or
242 at other bodychanges). Clear the data when the player goes
243 linkdead or quits. You won't need to save this data.
244 3.4. Lower_case() terminaltypes... ;)
245 3.5. Use reasonable defaultvalues if the client does not
246 support one of the options. (columns 80,lines 24 if not
247 NAWS, unknown or vt100 for no terminaltype)
248
249 The WILL/WONT/DO/DONT data is best saved in a mapping looking
250 like this:
251 ([ "received": ([ option1: DO_DONT_OR_0;WILL_WONT_OR_0, ... ])
252 , "sent" : ([ option1: DO_DONT_OR_0;WILL_WONT_OR_0, ... ])
253 ])
254
255 (Ok, it can be done better. But not without confusing *me*
256 more.)
257
258 Before sending anything check
259 TN["sent"][option,0_if_do_dont_or_1_if_will_wont]
260 so you don't enter endless loops, save network traffic and the
261 like.
262
263 The windowsize is best saved in the players environment
264 variables so that he can modify them later on. (Or in two
265 integers in the player object...). Use for these values is
266 clear I think.
267
268 The terminaltypes received using above mentioned method are
269 best stored in an array. The actual set terminaltype is best
270 stored in an environment variable where the player can modify
271 it. Upon modifying it the IAC SB TTYPE SEND IAC SE cycle
272 should be started to match the emulation to the entered new
273 terminaltype. You then may use data retrieved from
274 /etc/termcap (man 5 termcap) or /usr/lib/terminfo/*/* (SysVID,
275 man 5 terminfo) to implement terminalcontrol codes dependend
276 on the terminaltype. /etc/termcap may prove to be the easiest
277 way tough /usr/lib/terminfo/*/* is the newer (and better) SysV
278 way of doing it.
279
280 [Anyone got a description of the internal terminfo format for
281 me? -Marcus]
282
283 LINEMODE replies may be left alone if only using the mode
284 change to MODE_EDIT
285
286 Some statistics about what clients support telnet negotiations:
287
288 Tinyfugue and some other mudclients usually do not support
289 negotiations.
290 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
309
310BUGS
311 Not all aspects of the options are mentioned to keep this doc
312 at a reasonable size. Refer to the RFCs to get more confused.
313
314CREDITS
315 Provided by Marcus@TAPPMud (Marcus Meissner,
316 <msmeissn@cip.informatik.uni-erlangen.de>).