blob: 62a1893f8a4603b97a8532ca73921e6b8a538cb3 [file] [log] [blame]
Sean Middleditchb9e48642009-03-12 23:33:27 -04001=====================================================================
2 libtelnet - TELNET protocol handling library
3=====================================================================
4
Sean Middleditch892c5f12009-03-14 13:39:07 -04005 http://github.com/elanthis/libtelnet
6
7 Sean Middleditch
8 sean@sourcemud.org
Sean Middleditchb9e48642009-03-12 23:33:27 -04009
10---------------------------------------------------------------------
11The author or authors of this code dedicate any and all copyright
12interest in this code to the public domain. We make this dedication
13for the benefit of the public at large and to the detriment of our
14heirs and successors. We intend this dedication to be an overt act of
15relinquishment in perpetuity of all present and future rights to this
16code under copyright law.
17---------------------------------------------------------------------
18
Sean Middleditch9d2f98a2009-03-14 05:24:56 -040019*** TODO ***
20
21 - RFC 1143 option negotiation algorithm
22 - automatic MCCP2 handling (controllable by host app)
23 - efficient one-byte sub-requests
24 ? MCCP1
25 ? ZMP parsing
26 ? MSSP parsing
27 ? ENVIRON/NEW-ENVIRON parsing
28 ? telnet-status testing tool
29 ? few options to make telnet-proxy even more useful
30
Sean Middleditchb9e48642009-03-12 23:33:27 -040031I. INTRODUCTION
32=====================================================================
33
34libtelnet provides safe and correct handling of the core TELNET
35protocol. It does not include any "smarts," and all use of the
36protocol (such as deciding which options to support, enabling
37and disabling options, or processing subrequests) must be implemented
38by the application author.
39
Sean Middleditch892c5f12009-03-14 13:39:07 -040040For more information on the TELNET protocol, see:
41
42 http://www.faqs.org/rfcs/rfc854.html
43
Sean Middleditchb9e48642009-03-12 23:33:27 -040044II. LIBTELNET API
45=====================================================================
46
Sean Middleditch892c5f12009-03-14 13:39:07 -040047The libtelnet API contains several distinct parts. The first part is
48the basic initialization and deinitialization routines. The second
49part is a single function for pushing received data into the
50libtelnet processor. The third part is the libtelnet_send_*()
51functions, which generate TELNET commands and ensure data is properly
52formatted before sending over the wire. The final part is the
Sean Middleditch30323022009-03-14 21:45:28 -040053callback structure libtelnet_cb_t.
Sean Middleditch892c5f12009-03-14 13:39:07 -040054
55IIa. Initialization
56
57 struct libtelnet_t;
58 This structure represents the state of the TELNET protocol for a
59 single connection. Each connection utilizing TELNET must have
60 its own libtelnet_t structure, which is passed to all libtelnet
61 API calls.
62
Sean Middleditch30323022009-03-14 21:45:28 -040063 struct libtelnet_cb_t;
64 An instance of this structure must be initialized and have all
65 mandatory and desired optional callbacks set. See section IId
66 for more information.
67
Sean Middleditch892c5f12009-03-14 13:39:07 -040068 void libtelnet_init(struct libtelnet_t *telnet,
Sean Middleditch30323022009-03-14 21:45:28 -040069 struct libtelnet_cb_t *cb, enum libtelnet_mode_t mode);
Sean Middleditch892c5f12009-03-14 13:39:07 -040070 The libtelnet_init() function is responsible for initializing
71 the data in a libtelnet_t structure. It must be called
72 immediately after establishing a connection and before any other
73 libtelnet API calls are made.
74
Sean Middleditch30323022009-03-14 21:45:28 -040075 The cb parameter must be a pointer to a fully initialized
76 instance of libtelnet_cb_t. A single instance of the structure
77 can be shared between any number of libtelnet_t instances.
78
Sean Middleditchf66a7ee2009-03-15 11:54:07 -040079 The mode parameter must be one of LIBTELNET_MODE_SERVER,
80 LIBTELNET_MODE_CLIENT, or LIBTELNET_MODE_PROXY. These slightly
81 alter the behavior of libtelnet in certain instances. If you are
82 implementing a TELNET server, use the SERVER mode. If you are
83 implementing a client, use the CLIENT mode. The PROXY mode
84 enables special behavior for telnet-proxy (or similar
85 applications).
Sean Middleditch892c5f12009-03-14 13:39:07 -040086
87 boid libtelnet_free(struct libtelnet_t *telnet);
88 Releases any internal memory allocated by libtelnet. This must
89 be called whenever a connection is closed, or you will incur
90 memory leaks.
91
92IIb. Receiving Data
93
94 void libtelnet_push(struct libtelnet_t *telnet,
95 unsigned char *buffer, unsigned int size, void *user_data);
96 When your application receives data over the socket from the
97 remote end, it must pass the received bytes into this function.
98 Callback functions will be invoked as the buffer is processed,
99 and the user_data parameter will be passed to each callback.
100
101IIc. Sending Data
102
103 Note that all of the libtelnet_send_*() functions will invoke
Sean Middleditch30323022009-03-14 21:45:28 -0400104 the send callback function attached to the libtelnet_t instance.
105 The user_data parameter to each of these functions is passed
106 through to the callback.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400107
108 void libtelnet_send_command(struct libtelnet_t *telnet,
109 unsigned char cmd, void *user_data);
110 Sends a single "simple" TELNET command, such as the GO-AHEAD
111 commands (255 249).
112
113 void libtelnet_send_negotiate(struct libtelnet_t *telnet,
114 unsigned char cmd, unsigned char opt, void *user_data);
115 Sends a TELNET negotiation command. The cmd parameter must be
116 one of LIBTELNET_WILL, LIBTELNET_DONT, LIBTELNET_DO, or
117 LIBTELNET_DONT. The opt parameter is the option to
118 negotiate.
119
120 void libtelnet_send_data(struct libtelnet_t *telnet,
121 unsigned char *buffer, unsigned int size, void *user_data);
122 Sends raw data, which would be either the process output from
123 a server or the user input from a client.
124
125 void libtelnet_send_subnegotiation(struct libtelnet_t *telnet,
126 unsigned char opt, unsigned char *buffer, unsigned int size,
127 void *user_data);
128 Sends a TELNET sub-negotiation command. The opt parameter
129 is the sub-negotiation option.
130
131IId. Callbacks
132
Sean Middleditch30323022009-03-14 21:45:28 -0400133 The libtelnet_cb_t structure containers a number of callback
134 entry points. Of these, only the send and data callbacks are
135 absolutely required. All others are optional. The declarations
136 below show the signature of the callback functions.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400137
Sean Middleditch30323022009-03-14 21:45:28 -0400138 An example of initializing a libtelnet_cb_t structure:
139
140 /* illustrative data callback */
141 void my_data_cb(libtelnet_t *telnet, unsigned char *buffer,
142 unsigned int size, void *user_data) {
143 /* print number of bytes received and then show the
144 * whole buffer */
145 printf("RECV(%d): %.*s\n", size, size, buffer);
146 }
147
148 /* illustrative variable definitions */
149 libtelnet_t conn;
150 libtelnet_cb_t callbacks;
151
152 /* clear all callbacks and set just the ones we want */
153 memset(&callbacks, 0, sizeof(callbacks));
154 callbacks->send = my_send_cb;
155 callbacks->data = my_data_cb;
156
157 /* initialize the connection with our callbacks */
158 libtelnet_init(&conn, &callbacks, LIBTELNET_MODE_SERVER);
159
160 Remember that a single libtelnet_cb_t structure can be shared
161 between any number of libtelnet_t instances. There is no reason
162 to make multiple copies of the data if all of your connections
163 use the same callback functions.
164
165 void libtelnet_cb_t->data(struct libtelnet_t *telnet,
Sean Middleditch892c5f12009-03-14 13:39:07 -0400166 unsigned char *buffer, unsigned int size, void *user_data);
167 Regular data has been received by the remote end. For a server,
168 this would be input typed by the client; for a client, this is
169 process output generated by the server.
170
171 Note that data is not line-buffered by libtelnet. A single
172 line of input may be broken into pieces and given to
173 consecutive calls to libtelnet_data_cb(). If you are doing
174 line-based processing of data, it is your responsibility to
175 buffer data and find the line breaks.
176
Sean Middleditch30323022009-03-14 21:45:28 -0400177 void libtelnet_cb_t->send(struct libtelnet_t *telnet,
Sean Middleditch892c5f12009-03-14 13:39:07 -0400178 unsigned char *buffer, unsigned int size, void *user_data);
179 This is called whenever libtelnet has generated output to be
180 send to the remote end of the connection. In most cases this
181 will be a simple wrapper arround your applications network
182 output buffering/transmission code.
183
184 You can pass socket information through the user_data
185 parameter to libtelnet calls so that it is available in this
186 callback.
187
Sean Middleditch30323022009-03-14 21:45:28 -0400188 void libtelnet_cb_t->command(struct libtelnet_t *telnet,
Sean Middleditch892c5f12009-03-14 13:39:07 -0400189 unsigned char cmd, void *user_data);
190 Called whenever a "simpler" TELNET command has arrived, such
191 as GO-AHEAD commands (255 249). The necessary processing
192 depends on the specific commands; see the TELNET RFC for
193 more information.
194
Sean Middleditch30323022009-03-14 21:45:28 -0400195 void libtelnet_cb_t->negotiate(struct libtelnet_t *telnet,
Sean Middleditch892c5f12009-03-14 13:39:07 -0400196 unsigned char cmd, unsigned char opt, void *user_data);
197 This function is called whenever a TELNET negotiation command
198 has been received. The cmd parameter will be one of
199 LIBTELNET_WILL, LIBTELNET_WONT, LIBTELNET_DO, or LIBTELNET_DONT.
200 The opt parameter is the option being negotiated.
201
202 libtelnet does not currently manage negotiation for you. For
203 best practice in implementing TELNET negotiation, see:
204
205 http://www.faqs.org/rfcs/rfc1143.html
206
Sean Middleditch30323022009-03-14 21:45:28 -0400207 void libtelnet_cb_t->subnegotiation(struct libtelnet_t *telnet,
Sean Middleditch892c5f12009-03-14 13:39:07 -0400208 unsigned char opt, unsigned char *data, unsigned int size,
209 void *user_data);
210 Called whenever a TELNET sub-negotiation has been received.
211 Sub-negotiations include the NAWS option for communicating
212 terminal size to a server, the NEW-ENVIRON and TTYPE options
213 for negotiating terminal features, and MUD-centric protocols
214 such as ZMP, MSSP, and MCCP2.
215
216 The opt parameter is the option under sub-negotiation. The
217 remaining data (if any) is passed in the buffer.
218
Sean Middleditch30323022009-03-14 21:45:28 -0400219 void libtelnet_cb_t->compress(struct libtelnet_t *telnet,
Sean Middleditch892c5f12009-03-14 13:39:07 -0400220 char enabled, void *user_data);
221 The callback is invoked whenever the COMPRESS2 (MCCP2)
222 feature is enabled or disabled. For servers, this is called
223 immediately after beginning compression after a client accepts
224 the COMPRESS2 option. For clients, this is called immediately
225 after a compress stream begin or ends.
226
227 The enabled parameter is 1 if compression has begun and 0 if
228 compression has ended.
Sean Middleditchb9e48642009-03-12 23:33:27 -0400229
230III. INTEGRATING LIBTELNET
231=====================================================================
232
233FIXME: fill in notes about implementing the libtelnet_*_cb functions
234
Sean Middleditch892c5f12009-03-14 13:39:07 -0400235IV. SAFETY AND CORRECTNESS CONSIDERATIONS
Sean Middleditchb9e48642009-03-12 23:33:27 -0400236=====================================================================
237
Sean Middleditch892c5f12009-03-14 13:39:07 -0400238Your existing application may make heavy use of its own output
239buffering and transmission commands, including hand-made routines
240for sending TELNET commands and sub-negotiation requests. There are
241at times subtle issues that need to be handled when communication
242over the TELNET protocol, not least of which is the need to escape
243any byte value 0xFF with a special TELNET command.
Sean Middleditchb9e48642009-03-12 23:33:27 -0400244
Sean Middleditch892c5f12009-03-14 13:39:07 -0400245For these reasons, it is very important that applications making use
246of libtelnet always make use of the libtelnet_send_*() family of
247functions for all data being sent over the TELNET connection.
248
249V. MCCP2 COMPRESSION
Sean Middleditchb9e48642009-03-12 23:33:27 -0400250=====================================================================
251
Sean Middleditch892c5f12009-03-14 13:39:07 -0400252The MCCP2 (COMPRESS2) TELNET extension allows for the compression of
253all traffic sent from server to client. For more information:
254
255 http://www.mudbytes.net/index.php?a=articles&s=mccp
256
257libtelnet transparently supports MCCP2. For a server to support
258MCCP2, the application must begin negotiation of the COMPRESS2
259option using libtelnet_send_negotiate(), for example:
260
261 libtelnet_send_negotiate(&telnet, LIBTELNET_WILL,
262 LIBTELNET_OPTION_COMPRESS2, user_data);
263
264libtelnet will automatically detect if the client responds favoribly
265and will begin compressing data. For clients, no action must be
266taken, as libtelnet will automatically handle the requests.
267
268NOTE: libtelnet will still invoke the callback functions for
269negotiation and sub-negotiation commands relating to MCCP2. Do not
270respond to these.
271
272In order for libtelnet to support MCCP2, zlib must be installed and
273enabled when compiling libtelnet. Use -DHAVE_ZLIB to enable zlib
274when compiling libtelnet.c and pass -lz to the linker to link in the
275zlib shared library.
276
277VI. TELNET PROXY UTILITY
278=====================================================================
279
280The telnet-proxy utility is a small application that serves both as
281a testbed for libtelnet and as a powerful debugging tool for TELNET
282servers and clients.
283
284To use telnet-proxy, you must first compile it using:
285
286 $ make
287
288If you do not have zlib installed and wish to disable MCCP2 support
289then you must first edit the Makefile and remove the -DHAVE_ZLIB and
290the -lz from the compile flags.
291
Sean Middleditchd88f1832009-03-15 01:06:17 -0400292To run telnet-proxy, you simply give it the server's host name or
293IP address, the server's port number, and the port number that
294telnet-proxy should listen on. For example, to connect to the server
295on mud.example.com port 7800 and to listen on port 5000, run:
Sean Middleditch892c5f12009-03-14 13:39:07 -0400296
Sean Middleditchd88f1832009-03-15 01:06:17 -0400297 $ ./telnet-proxy mud.example.com 7800 5000
Sean Middleditch892c5f12009-03-14 13:39:07 -0400298
299You can then connect to the host telnet-proxy is running on (e.g.
Sean Middleditchd88f1832009-03-15 01:06:17 -0400300127.0.0.1) on port 500 and you will automatically be proxied into
301mud.example.com.
Sean Middleditch892c5f12009-03-14 13:39:07 -0400302
303telnet-proxy will display status information about the data
304passing through both ends of the tunnel. Once either end
305disconnects, telnet-proxy will close. telnet-proxy can only
306support a single tunnel at a time and must be restarted for each
307connection.