blob: a7bb3fd0a979988dcccaffedaf68c147611b37af [file] [log] [blame]
Sean Middleditch29144852009-03-12 23:14:47 -04001/*
Sean Middleditch9de15982009-03-14 03:35:49 -04002 * Sean Middleditch
3 * sean@sourcemud.org
4 *
Sean Middleditch29144852009-03-12 23:14:47 -04005 * The author or authors of this code dedicate any and all copyright interest
6 * in this code to the public domain. We make this dedication for the benefit
7 * of the public at large and to the detriment of our heirs and successors. We
8 * intend this dedication to be an overt act of relinquishment in perpetuity of
9 * all present and future rights to this code under copyright law.
10 */
11
Sean Middleditch6aef0732009-03-12 23:27:35 -040012#if !defined(LIBTELNET_INCLUDE)
Sean Middleditchaac2c122009-03-14 18:31:26 -040013#define LIBTELNET_INCLUDE 1
Sean Middleditch6aef0732009-03-12 23:27:35 -040014
Sean Middleditch30323022009-03-14 21:45:28 -040015/* forward declarations */
Sean Middleditchf65f27d2009-03-19 02:32:04 -040016typedef struct telnet_t telnet_t;
17typedef struct telnet_event_t telnet_event_t;
Sean Middleditch30323022009-03-14 21:45:28 -040018
Sean Middleditch29144852009-03-12 23:14:47 -040019/* telnet special values */
Sean Middleditchf65f27d2009-03-19 02:32:04 -040020#define TELNET_IAC 255
21#define TELNET_DONT 254
22#define TELNET_DO 253
23#define TELNET_WONT 252
24#define TELNET_WILL 251
25#define TELNET_SB 250
26#define TELNET_SB 250
27#define TELNET_GA 249
28#define TELNET_EL 248
29#define TELNET_EC 247
30#define TELNET_AYT 246
31#define TELNET_AO 245
32#define TELNET_IP 244
33#define TELNET_BREAK 243
34#define TELNET_DM 242
35#define TELNET_NOP 241
36#define TELNET_SE 240
37#define TELNET_EOR 239
38#define TELNET_ABORT 238
39#define TELNET_SUSP 237
40#define TELNET_EOF 236
Sean Middleditch29144852009-03-12 23:14:47 -040041
42/* telnet options */
Sean Middleditchf65f27d2009-03-19 02:32:04 -040043#define TELNET_TELOPT_BINARY 0
44#define TELNET_TELOPT_ECHO 1
45#define TELNET_TELOPT_RCP 2
46#define TELNET_TELOPT_SGA 3
47#define TELNET_TELOPT_NAMS 4
48#define TELNET_TELOPT_STATUS 5
49#define TELNET_TELOPT_TM 6
50#define TELNET_TELOPT_RCTE 7
51#define TELNET_TELOPT_NAOL 8
52#define TELNET_TELOPT_NAOP 9
53#define TELNET_TELOPT_NAOCRD 10
54#define TELNET_TELOPT_NAOHTS 11
55#define TELNET_TELOPT_NAOHTD 12
56#define TELNET_TELOPT_NAOFFD 13
57#define TELNET_TELOPT_NAOVTS 14
58#define TELNET_TELOPT_NAOVTD 15
59#define TELNET_TELOPT_NAOLFD 16
60#define TELNET_TELOPT_XASCII 17
61#define TELNET_TELOPT_LOGOUT 18
62#define TELNET_TELOPT_BM 19
63#define TELNET_TELOPT_DET 20
64#define TELNET_TELOPT_SUPDUP 21
65#define TELNET_TELOPT_SUPDUPOUTPUT 22
66#define TELNET_TELOPT_SNDLOC 23
67#define TELNET_TELOPT_TTYPE 24
68#define TELNET_TELOPT_EOR 25
69#define TELNET_TELOPT_TUID 26
70#define TELNET_TELOPT_OUTMRK 27
71#define TELNET_TELOPT_TTYLOC 28
72#define TELNET_TELOPT_3270REGIME 29
73#define TELNET_TELOPT_X3PAD 30
74#define TELNET_TELOPT_NAWS 31
75#define TELNET_TELOPT_TSPEED 32
76#define TELNET_TELOPT_LFLOW 33
77#define TELNET_TELOPT_LINEMODE 34
78#define TELNET_TELOPT_XDISPLOC 35
79#define TELNET_TELOPT_ENVIRON 36
80#define TELNET_TELOPT_AUTHENTICATION 37
81#define TELNET_TELOPT_ENCRYPT 38
82#define TELNET_TELOPT_NEW_ENVIRON 39
83#define TELNET_TELOPT_COMPRESS 85
84#define TELNET_TELOPT_COMPRESS2 86
85#define TELNET_TELOPT_ZMP 93
86#define TELNET_TELOPT_EXOPL 255
Sean Middleditch29144852009-03-12 23:14:47 -040087
Sean Middleditch08bb05f2009-03-15 23:29:46 -040088/* libtelnet feature flags */
Sean Middleditchf65f27d2009-03-19 02:32:04 -040089#define TELNET_FLAG_PROXY (1<<0)
Sean Middleditch61f8eb62009-03-14 04:57:27 -040090
Sean Middleditchf65f27d2009-03-19 02:32:04 -040091#define TELNET_PFLAG_DEFLATE (1<<7)
Sean Middleditch29144852009-03-12 23:14:47 -040092
93/* telnet states */
Sean Middleditchf65f27d2009-03-19 02:32:04 -040094enum telnet_state_t {
95 TELNET_STATE_DATA = 0,
96 TELNET_STATE_IAC,
97 TELNET_STATE_DO,
98 TELNET_STATE_DONT,
99 TELNET_STATE_WILL,
100 TELNET_STATE_WONT,
101 TELNET_STATE_SB,
102 TELNET_STATE_SB_DATA,
103 TELNET_STATE_SB_DATA_IAC
Sean Middleditch29144852009-03-12 23:14:47 -0400104};
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400105typedef enum telnet_state_t telnet_state_t;
Sean Middleditch29144852009-03-12 23:14:47 -0400106
107/* error codes */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400108enum telnet_error_t {
109 TELNET_EOK = 0,
110 TELNET_EBADVAL, /* invalid parameter, or API misuse */
111 TELNET_ENOMEM, /* memory allocation failure */
112 TELNET_EOVERFLOW, /* data exceeds buffer size */
113 TELNET_EPROTOCOL, /* invalid sequence of special bytes */
114 TELNET_ECOMPRESS /* error handling compressed streams */
Sean Middleditch29144852009-03-12 23:14:47 -0400115};
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400116typedef enum telnet_error_t telnet_error_t;
Sean Middleditch29144852009-03-12 23:14:47 -0400117
Sean Middleditch637df7f2009-03-15 12:57:32 -0400118/* event codes */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400119enum telnet_event_type_t {
120 TELNET_EV_DATA = 0,
121 TELNET_EV_SEND,
122 TELNET_EV_IAC,
123 TELNET_EV_WILL,
124 TELNET_EV_WONT,
125 TELNET_EV_DO,
126 TELNET_EV_DONT,
127 TELNET_EV_SUBNEGOTIATION,
128 TELNET_EV_COMPRESS,
129 TELNET_EV_WARNING,
130 TELNET_EV_ERROR
Sean Middleditch30323022009-03-14 21:45:28 -0400131};
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400132typedef enum telnet_event_type_t telnet_event_type_t;
Sean Middleditch30323022009-03-14 21:45:28 -0400133
Sean Middleditch637df7f2009-03-15 12:57:32 -0400134/* event information */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400135struct telnet_event_t {
Sean Middleditch637df7f2009-03-15 12:57:32 -0400136 /* data buffer: for DATA, SEND, SUBNEGOTIATION, and ERROR events */
Sean Middleditch8daf7742009-03-19 02:05:24 -0400137 const char *buffer;
Sean Middleditch340a51b2009-03-19 02:08:46 -0400138 size_t size;
Sean Middleditch5b5bc922009-03-15 23:02:10 -0400139 /* type of event */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400140 enum telnet_event_type_t type;
Sean Middleditch5b5bc922009-03-15 23:02:10 -0400141 /* IAC command */
142 unsigned char command;
143 /* telopt info: for negotiation events SUBNEGOTIATION */
144 unsigned char telopt;
145 /* accept status: for WILL and DO events */
146 unsigned char accept;
147};
148
Sean Middleditch637df7f2009-03-15 12:57:32 -0400149/* event handler declaration */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400150typedef void (*telnet_event_handler_t)(telnet_t *telnet,
151 telnet_event_t *event, void *user_data);
Sean Middleditch637df7f2009-03-15 12:57:32 -0400152
Sean Middleditch4d9444d2009-03-13 22:48:05 -0400153/* state tracker */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400154struct telnet_t {
Sean Middleditch9f79cc52009-03-15 13:39:24 -0400155 /* user data */
156 void *ud;
Sean Middleditch637df7f2009-03-15 12:57:32 -0400157 /* event handler */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400158 telnet_event_handler_t eh;
Sean Middleditch9de15982009-03-14 03:35:49 -0400159#ifdef HAVE_ZLIB
Sean Middleditch30323022009-03-14 21:45:28 -0400160 /* zlib (mccp2) compression */
Sean Middleditchfbe93e32009-03-15 23:39:31 -0400161 z_stream *z;
Sean Middleditch9de15982009-03-14 03:35:49 -0400162#endif
Sean Middleditch5b5bc922009-03-15 23:02:10 -0400163 /* RFC1143 option negotiation states */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400164 struct telnet_rfc1143_t *q;
Sean Middleditch4d9444d2009-03-13 22:48:05 -0400165 /* sub-request buffer */
Sean Middleditch8daf7742009-03-19 02:05:24 -0400166 char *buffer;
Sean Middleditch4d9444d2009-03-13 22:48:05 -0400167 /* current size of the buffer */
Sean Middleditch340a51b2009-03-19 02:08:46 -0400168 size_t buffer_size;
Sean Middleditch5b5bc922009-03-15 23:02:10 -0400169 /* current buffer write position (also length of buffer data) */
Sean Middleditch340a51b2009-03-19 02:08:46 -0400170 size_t buffer_pos;
Sean Middleditch4d9444d2009-03-13 22:48:05 -0400171 /* current state */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400172 enum telnet_state_t state;
Sean Middleditch08bb05f2009-03-15 23:29:46 -0400173 /* option flags */
174 unsigned char flags;
Sean Middleditchda0e6952009-03-15 13:28:09 -0400175 /* current subnegotiation telopt */
176 unsigned char sb_telopt;
Sean Middleditch5b5bc922009-03-15 23:02:10 -0400177 /* length of RFC1143 queue */
178 unsigned char q_size;
Sean Middleditch4d9444d2009-03-13 22:48:05 -0400179};
180
Sean Middleditch29144852009-03-12 23:14:47 -0400181/* initialize a telnet state tracker */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400182extern void telnet_init(telnet_t *telnet, telnet_event_handler_t eh,
Sean Middleditch08bb05f2009-03-15 23:29:46 -0400183 unsigned char flags, void *user_data);
Sean Middleditch29144852009-03-12 23:14:47 -0400184
185/* free up any memory allocated by a state tracker */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400186extern void telnet_free(telnet_t *telnet);
Sean Middleditch29144852009-03-12 23:14:47 -0400187
Sean Middleditch29144852009-03-12 23:14:47 -0400188/* push a byte buffer into the state tracker */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400189extern void telnet_push(telnet_t *telnet, const char *buffer,
Sean Middleditch340a51b2009-03-19 02:08:46 -0400190 size_t size);
Sean Middleditch29144852009-03-12 23:14:47 -0400191
192/* send an iac command */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400193extern void telnet_send_command(telnet_t *telnet, unsigned char cmd);
Sean Middleditch29144852009-03-12 23:14:47 -0400194
Sean Middleditch2b4bfc42009-03-16 01:25:52 -0400195/* send negotiation, with RFC1143 checking.
196 * will not actually send unless necessary, but will update internal
197 * negotiation queue.
198 */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400199extern void telnet_send_negotiate(telnet_t *telnet, unsigned char cmd,
Sean Middleditch812358d2009-03-15 23:24:03 -0400200 unsigned char opt);
Sean Middleditch29144852009-03-12 23:14:47 -0400201
202/* send non-command data (escapes IAC bytes) */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400203extern void telnet_send_data(telnet_t *telnet,
Sean Middleditch340a51b2009-03-19 02:08:46 -0400204 const char *buffer, size_t size);
Sean Middleditch29144852009-03-12 23:14:47 -0400205
Sean Middleditch90e79da2009-03-19 15:17:13 -0400206/* send IAC SB followed by the telopt code */
207extern void telnet_begin_subnegotiation(telnet_t *telnet,
208 unsigned char telopt);
209
210/* send IAC SE */
211#define telnet_finish_subnegotiation(telnet) \
Sean Middleditch78943842009-03-19 15:22:06 -0400212 telnet_send_command((telnet), TELNET_SE)
Sean Middleditch90e79da2009-03-19 15:17:13 -0400213
214/* shortcut for sending a complete subnegotiation buffer.
215 * equivalent to:
216 * telnet_begin_subnegotiation(telnet, telopt);
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400217 * telnet_send_data(telnet, buffer, size);
Sean Middleditch90e79da2009-03-19 15:17:13 -0400218 * telnet_finish_subnegotiation(telnet);
Sean Middleditch2b4bfc42009-03-16 01:25:52 -0400219 */
Sean Middleditch90e79da2009-03-19 15:17:13 -0400220extern void telnet_send_subnegotiation(telnet_t *telnet, unsigned char telopt,
221 const char *buffer, size_t size);
Sean Middleditch6aef0732009-03-12 23:27:35 -0400222
Sean Middleditch124a1c22009-03-15 13:20:03 -0400223/* begin sending compressed data (server only) */
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400224extern void telnet_begin_compress2(telnet_t *telnet);
Sean Middleditch124a1c22009-03-15 13:20:03 -0400225
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400226/* printf type checking feature in GCC and some other compilers */
Sean Middleditchb7bf8f32009-03-19 18:18:22 -0400227#if __GNUC__
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400228# define TELNET_GNU_PRINTF(f,a) __attribute__((printf(f, a)))
Sean Middleditchd58f49f2009-03-16 12:49:35 -0400229#else
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400230# define TELNET_GNU_PRINTF(f,a)
Sean Middleditchd58f49f2009-03-16 12:49:35 -0400231#endif
232
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400233/* send formatted data with \r and \n translated, and IAC escaped */
234extern int telnet_printf(telnet_t *telnet, const char *fmt, ...);
Sean Middleditch4a156042009-03-16 17:10:58 -0400235
Sean Middleditchf65f27d2009-03-19 02:32:04 -0400236/* send formatted data with just IAC escaped */
237extern int telnet_printf2(telnet_t *telnet, const char *fmt, ...);
Sean Middleditchd58f49f2009-03-16 12:49:35 -0400238
Sean Middleditch6aef0732009-03-12 23:27:35 -0400239#endif /* !defined(LIBTELNET_INCLUDE) */