This source file includes following definitions.
- _send
- _check_telopt
- _get_rfc1143
- _set_rfc1143
- _send_negotiate
- _negotiate
- _environ_telnet
- _ttype_telnet
- _subnegotiate
- telnet_init
- telnet_free
- _buffer_byte
- _process
- telnet_recv
- telnet_iac
- telnet_negotiate
- telnet_send
- telnet_send_text
- telnet_begin_sb
- telnet_vprintf
- telnet_printf
- telnet_raw_vprintf
- telnet_raw_printf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 #include <stdlib.h>
56 #include <string.h>
57 #include <stdio.h>
58 #include <errno.h>
59 #include <string.h>
60 #include <stdarg.h>
61
62 #ifdef __GNUC__
63 # define NO_RETURN __attribute__ ((noreturn))
64 # define UNUSED __attribute__ ((unused))
65 #else
66 # define NO_RETURN
67 # define UNUSED
68 #endif
69
70
71 #if defined(_WIN32)
72 # define __func__ __FUNCTION__
73 # if defined(_MSC_VER)
74 # if _MSC_VER <= 1700
75 # define va_copy(dest, src) (dest = src)
76 # endif
77 # endif
78 #endif
79
80 #include "libtelnet.h"
81
82 #undef FREE
83 #define FREE(p) do \
84 { \
85 free((p)); \
86 (p) = NULL; \
87 } while(0)
88
89 #ifdef TESTING
90 # undef realloc
91 # undef FREE
92 # define FREE(p) free(p)
93 # define realloc trealloc
94 #endif
95
96
97 #define Q_US(q) ((q).state & 0x0F)
98 #define Q_HIM(q) (((q).state & 0xF0) >> 4)
99 #define Q_MAKE(us,him) ((us) | ((him) << 4))
100
101
102 #define NEGOTIATE_EVENT(telnet,cmd,opt) \
103 ev.type = (cmd); \
104 ev.neg.telopt = (opt); \
105 (telnet)->eh((telnet), &ev, (telnet)->ud);
106
107
108 enum telnet_state_t {
109 TELNET_STATE_DATA = 0,
110 TELNET_STATE_EOL,
111 TELNET_STATE_IAC,
112 TELNET_STATE_WILL,
113 TELNET_STATE_WONT,
114 TELNET_STATE_DO,
115 TELNET_STATE_DONT,
116 TELNET_STATE_SB,
117 TELNET_STATE_SB_DATA,
118 TELNET_STATE_SB_DATA_IAC
119 };
120 typedef enum telnet_state_t telnet_state_t;
121
122
123 struct telnet_t {
124
125 void *ud;
126
127 const telnet_telopt_t *telopts;
128
129 telnet_event_handler_t eh;
130
131 struct telnet_rfc1143_t *q;
132
133 char *buffer;
134
135 size_t buffer_size;
136
137 size_t buffer_pos;
138
139 enum telnet_state_t state;
140
141 unsigned char flags;
142
143 unsigned char sb_telopt;
144
145 unsigned int q_size;
146
147 unsigned int q_cnt;
148 };
149
150
151 typedef struct telnet_rfc1143_t {
152 unsigned char telopt;
153 unsigned char state;
154 } telnet_rfc1143_t;
155
156
157 #define Q_NO 0
158 #define Q_YES 1
159 #define Q_WANTNO 2
160 #define Q_WANTYES 3
161 #define Q_WANTNO_OP 4
162 #define Q_WANTYES_OP 5
163
164
165 static const char CRLF[] = { '\r', '\n' };
166 static const char CRNUL[] = { '\r', '\0' };
167
168
169 static const size_t _buffer_sizes[] = { 0, 512, 2048, 8192, 16384, };
170 static const size_t _buffer_sizes_count = sizeof(_buffer_sizes) /
171 sizeof(_buffer_sizes[0]);
172
173
174 static telnet_error_t _error(telnet_t *telnet, unsigned line,
175 const char* func, telnet_error_t err,
176 int fatal, const char *fmt, ...) {
177 telnet_event_t ev;
178 char buffer[512];
179 va_list va;
180
181
182 va_start(va, fmt);
183 vsnprintf(buffer, sizeof(buffer), fmt, va);
184 va_end(va);
185
186
187 ev.type = fatal ? TELNET_EV_ERROR : TELNET_EV_WARNING;
188 ev.error.file = __FILE__;
189 ev.error.func = func;
190 ev.error.line = (int) line;
191 ev.error.msg = buffer;
192 telnet->eh(telnet, &ev, telnet->ud);
193
194 return err;
195 }
196
197
198 static void _send(telnet_t *telnet, const char *buffer,
199 size_t size) {
200 telnet_event_t ev;
201
202 ev.type = TELNET_EV_SEND;
203 ev.data.buffer = buffer;
204 ev.data.size = size;
205 telnet->eh(telnet, &ev, telnet->ud);
206 }
207
208
209 #define _sendu(t, d, s) _send((t), (const char*)(d), (s))
210
211
212
213
214
215
216
217 static __inline__ int _check_telopt(telnet_t *telnet, unsigned char telopt,
218 int us) {
219 int i;
220
221
222 if (telnet->telopts == 0)
223 return 0;
224
225
226 for (i = 0; telnet->telopts[i].telopt != -1; ++i) {
227 if (telnet->telopts[i].telopt == telopt) {
228 if (us && telnet->telopts[i].us == TELNET_WILL)
229 return 1;
230 else if (!us && telnet->telopts[i].him == TELNET_DO)
231 return 1;
232 else
233 return 0;
234 }
235 }
236
237
238 return 0;
239 }
240
241
242 static __inline__ telnet_rfc1143_t _get_rfc1143(telnet_t *telnet,
243 unsigned char telopt) {
244 telnet_rfc1143_t empty;
245 unsigned int i;
246
247
248 for (i = 0; i != telnet->q_cnt; ++i) {
249 if (telnet->q[i].telopt == telopt) {
250 return telnet->q[i];
251 }
252 }
253
254
255 empty.telopt = telopt;
256 empty.state = 0;
257 return empty;
258 }
259
260
261 static __inline__ void _set_rfc1143(telnet_t *telnet, unsigned char telopt,
262 unsigned char us, unsigned char him) {
263 telnet_rfc1143_t *qtmp;
264 unsigned int i;
265
266
267 for (i = 0; i != telnet->q_cnt; ++i) {
268 if (telnet->q[i].telopt == telopt) {
269 telnet->q[i].state = (unsigned char) Q_MAKE(us,him);
270 if (telopt != TELNET_TELOPT_BINARY)
271 return;
272 telnet->flags &=
273 (unsigned char)~(TELNET_FLAG_TRANSMIT_BINARY |
274 TELNET_FLAG_RECEIVE_BINARY);
275 if (us == Q_YES)
276 telnet->flags |= TELNET_FLAG_TRANSMIT_BINARY;
277 if (him == Q_YES)
278 telnet->flags |= TELNET_FLAG_RECEIVE_BINARY;
279 return;
280 }
281 }
282
283
284
285
286
287
288
289
290
291 #define QUANTUM 4
292
293 if (i >= telnet->q_size) {
294
295 if ((qtmp = (telnet_rfc1143_t *)realloc(telnet->q,
296 sizeof(telnet_rfc1143_t) * (telnet->q_size + QUANTUM))) == 0) {
297 _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0,
298 "realloc() failed: %s", strerror(errno));
299 return;
300 }
301 memset(&qtmp[telnet->q_size], 0, sizeof(telnet_rfc1143_t) * QUANTUM);
302 telnet->q = qtmp;
303 telnet->q_size += QUANTUM;
304 }
305
306 telnet->q[telnet->q_cnt].telopt = telopt;
307 telnet->q[telnet->q_cnt].state = (unsigned char) Q_MAKE(us, him);
308 telnet->q_cnt ++;
309 }
310
311
312 static __inline__ void _send_negotiate(telnet_t *telnet, unsigned char cmd,
313 unsigned char telopt) {
314 unsigned char bytes[3];
315 bytes[0] = TELNET_IAC;
316 bytes[1] = cmd;
317 bytes[2] = telopt;
318 _sendu(telnet, bytes, 3);
319 }
320
321
322 static void _negotiate(telnet_t *telnet, unsigned char telopt) {
323 telnet_event_t ev;
324 telnet_rfc1143_t q;
325
326
327 if (telnet->flags & TELNET_FLAG_PROXY) {
328 switch ((int)telnet->state) {
329 case TELNET_STATE_WILL:
330 NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt);
331 break;
332 case TELNET_STATE_WONT:
333 NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt);
334 break;
335 case TELNET_STATE_DO:
336 NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt);
337 break;
338 case TELNET_STATE_DONT:
339 NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt);
340 break;
341 }
342 return;
343 }
344
345
346 q = _get_rfc1143(telnet, telopt);
347
348
349 switch ((int)telnet->state) {
350
351 case TELNET_STATE_WILL:
352 switch (Q_HIM(q)) {
353 case Q_NO:
354 if (_check_telopt(telnet, telopt, 0)) {
355 _set_rfc1143(telnet, telopt, Q_US(q), Q_YES);
356 _send_negotiate(telnet, TELNET_DO, telopt);
357 NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt);
358 } else
359 _send_negotiate(telnet, TELNET_DONT, telopt);
360 break;
361 case Q_WANTNO:
362 _set_rfc1143(telnet, telopt, Q_US(q), Q_NO);
363 NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt);
364 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
365 "DONT answered by WILL");
366 break;
367 case Q_WANTNO_OP:
368 _set_rfc1143(telnet, telopt, Q_US(q), Q_YES);
369 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
370 "DONT answered by WILL");
371 break;
372 case Q_WANTYES:
373 _set_rfc1143(telnet, telopt, Q_US(q), Q_YES);
374 NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt);
375 break;
376 case Q_WANTYES_OP:
377 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO);
378 _send_negotiate(telnet, TELNET_DONT, telopt);
379 NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt);
380 break;
381 }
382 break;
383
384
385 case TELNET_STATE_WONT:
386 switch (Q_HIM(q)) {
387 case Q_YES:
388 _set_rfc1143(telnet, telopt, Q_US(q), Q_NO);
389 _send_negotiate(telnet, TELNET_DONT, telopt);
390 NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt);
391 break;
392 case Q_WANTNO:
393 _set_rfc1143(telnet, telopt, Q_US(q), Q_NO);
394 NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt);
395 break;
396 case Q_WANTNO_OP:
397 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES);
398 _send_negotiate(telnet, TELNET_DO, telopt);
399 NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt);
400 break;
401 case Q_WANTYES:
402 case Q_WANTYES_OP:
403 _set_rfc1143(telnet, telopt, Q_US(q), Q_NO);
404 break;
405 }
406 break;
407
408
409 case TELNET_STATE_DO:
410 switch (Q_US(q)) {
411 case Q_NO:
412 if (_check_telopt(telnet, telopt, 1)) {
413 _set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q));
414 _send_negotiate(telnet, TELNET_WILL, telopt);
415 NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt);
416 } else
417 _send_negotiate(telnet, TELNET_WONT, telopt);
418 break;
419 case Q_WANTNO:
420 _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q));
421 NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt);
422 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
423 "WONT answered by DO");
424 break;
425 case Q_WANTNO_OP:
426 _set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q));
427 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
428 "WONT answered by DO");
429 break;
430 case Q_WANTYES:
431 _set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q));
432 NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt);
433 break;
434 case Q_WANTYES_OP:
435 _set_rfc1143(telnet, telopt, Q_WANTNO, Q_HIM(q));
436 _send_negotiate(telnet, TELNET_WONT, telopt);
437 NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt);
438 break;
439 }
440 break;
441
442
443 case TELNET_STATE_DONT:
444 switch (Q_US(q)) {
445 case Q_YES:
446 _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q));
447 _send_negotiate(telnet, TELNET_WONT, telopt);
448 NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt);
449 break;
450 case Q_WANTNO:
451 _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q));
452 NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt);
453 break;
454 case Q_WANTNO_OP:
455 _set_rfc1143(telnet, telopt, Q_WANTYES, Q_HIM(q));
456 _send_negotiate(telnet, TELNET_WILL, telopt);
457 NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt);
458 break;
459 case Q_WANTYES:
460 case Q_WANTYES_OP:
461 _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q));
462 break;
463 }
464 break;
465 }
466 }
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482 static int _environ_telnet(telnet_t *telnet, unsigned char type,
483 char* buffer, size_t size) {
484 telnet_event_t ev;
485 struct telnet_environ_t *values = 0;
486 char *c, *last, *out;
487 size_t eindex, count;
488
489
490 if (size == 0) {
491 return 0;
492 }
493
494
495 if ((unsigned)buffer[0] != TELNET_ENVIRON_SEND &&
496 (unsigned)buffer[0] != TELNET_ENVIRON_IS &&
497 (unsigned)buffer[0] != TELNET_ENVIRON_INFO) {
498 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
499 "telopt %ld subneg has invalid command", (long) type);
500 return 0;
501 }
502
503
504 ev.environ.cmd = (unsigned char) buffer[0];
505
506
507 if (size == 1) {
508
509 ev.environ.values = 0;
510 ev.environ.size = 0;
511
512
513 ev.type = TELNET_EV_ENVIRON;
514 telnet->eh(telnet, &ev, telnet->ud);
515
516 return 0;
517 }
518
519
520 if ((unsigned)buffer[1] != TELNET_ENVIRON_VAR &&
521 (unsigned)buffer[1] != TELNET_ENVIRON_USERVAR) {
522 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
523 "telopt %d subneg missing variable type", type);
524 return 0;
525 }
526
527
528 if ((unsigned)buffer[size - 1] == TELNET_ENVIRON_ESC) {
529 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
530 "telopt %d subneg ends with ESC", type);
531 return 0;
532 }
533
534
535 count = 0;
536 for (c = buffer + 1; c < buffer + size; ++c) {
537 if (*c == TELNET_ENVIRON_VAR || *c == TELNET_ENVIRON_USERVAR) {
538 ++count;
539 } else if (*c == TELNET_ENVIRON_ESC) {
540
541 ++c;
542 }
543 }
544
545
546 if ((values = (struct telnet_environ_t *)calloc(count,
547 sizeof(struct telnet_environ_t))) == 0) {
548 _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0,
549 "calloc() failed: %s", strerror(errno));
550 return 0;
551 }
552
553
554 out = buffer;
555 c = buffer + 1;
556 for (eindex = 0; eindex != count; ++eindex) {
557
558 values[eindex].type = (unsigned char) (*c++);
559
560
561
562 last = out;
563 while (c < buffer + size) {
564
565 if ((unsigned)*c == TELNET_ENVIRON_VAR ||
566 (unsigned)*c == TELNET_ENVIRON_VALUE ||
567 (unsigned)*c == TELNET_ENVIRON_USERVAR) {
568 break;
569 }
570
571
572 if (*c == TELNET_ENVIRON_ESC) {
573 ++c;
574 }
575
576 *out++ = *c++;
577 }
578 *out++ = '\0';
579
580
581 values[eindex].var = last;
582 values[eindex].value = "";
583
584
585
586 if (c < buffer + size && *c == TELNET_ENVIRON_VALUE) {
587 ++c;
588 last = out;
589 while (c < buffer + size) {
590
591 if ((unsigned)*c == TELNET_ENVIRON_VAR ||
592 (unsigned)*c == TELNET_ENVIRON_USERVAR) {
593 break;
594 }
595
596
597 if (*c == TELNET_ENVIRON_ESC) {
598 ++c;
599 }
600
601 *out++ = *c++;
602 }
603 *out++ = '\0';
604
605
606 values[eindex].value = last;
607 }
608 }
609
610
611 ev.environ.values = values;
612 ev.environ.size = count;
613
614
615 ev.type = TELNET_EV_ENVIRON;
616 telnet->eh(telnet, &ev, telnet->ud);
617
618
619 FREE(values);
620 return 0;
621 }
622
623
624 static int _ttype_telnet(telnet_t *telnet, const char* buffer, size_t size) {
625 telnet_event_t ev;
626
627
628 if (size == 0) {
629 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
630 "incomplete TERMINAL-TYPE request");
631 return 0;
632 }
633
634
635 if (buffer[0] != TELNET_TTYPE_IS &&
636 buffer[0] != TELNET_TTYPE_SEND) {
637 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
638 "TERMINAL-TYPE request has invalid type");
639 return 0;
640 }
641
642
643 if (buffer[0] == TELNET_TTYPE_IS) {
644 char *name;
645
646
647 if ((name = (char *)malloc(size)) == 0) {
648 _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0,
649 "malloc() failed: %s", strerror(errno));
650 return 0;
651 }
652 memcpy(name, buffer + 1, size - 1);
653 name[size - 1] = '\0';
654
655 ev.type = TELNET_EV_TTYPE;
656 ev.ttype.cmd = TELNET_TTYPE_IS;
657 ev.ttype.name = name;
658 telnet->eh(telnet, &ev, telnet->ud);
659
660
661 FREE(name);
662 } else {
663 ev.type = TELNET_EV_TTYPE;
664 ev.ttype.cmd = TELNET_TTYPE_SEND;
665 ev.ttype.name = 0;
666 telnet->eh(telnet, &ev, telnet->ud);
667 }
668
669 return 0;
670 }
671
672
673
674
675
676
677 static int _subnegotiate(telnet_t *telnet) {
678 telnet_event_t ev;
679
680
681 ev.type = TELNET_EV_SUBNEGOTIATION;
682 ev.sub.telopt = telnet->sb_telopt;
683 ev.sub.buffer = telnet->buffer;
684 ev.sub.size = telnet->buffer_pos;
685 telnet->eh(telnet, &ev, telnet->ud);
686
687 switch (telnet->sb_telopt) {
688
689
690 case TELNET_TELOPT_TTYPE:
691 return _ttype_telnet(telnet, telnet->buffer, telnet->buffer_pos);
692 case TELNET_TELOPT_ENVIRON:
693 case TELNET_TELOPT_NEW_ENVIRON:
694 return _environ_telnet(telnet, telnet->sb_telopt, telnet->buffer,
695 telnet->buffer_pos);
696 default:
697 return 0;
698 }
699 }
700
701
702 telnet_t *telnet_init(const telnet_telopt_t *telopts,
703 telnet_event_handler_t eh, unsigned char flags, void *user_data) {
704
705 struct telnet_t *telnet = (telnet_t*)calloc(1, sizeof(telnet_t));
706 if (telnet == 0)
707 return 0;
708
709
710 telnet->ud = user_data;
711 telnet->telopts = telopts;
712 telnet->eh = eh;
713 telnet->flags = flags;
714
715 return telnet;
716 }
717
718
719 void telnet_free(telnet_t *telnet) {
720
721 if (telnet->buffer != 0) {
722 FREE(telnet->buffer);
723 telnet->buffer = 0;
724 telnet->buffer_size = 0;
725 telnet->buffer_pos = 0;
726 }
727
728
729 if (telnet->q) {
730 FREE(telnet->q);
731 telnet->q = NULL;
732 telnet->q_size = 0;
733 telnet->q_cnt = 0;
734 }
735
736
737 free(telnet);
738 }
739
740
741 static telnet_error_t _buffer_byte(telnet_t *telnet,
742 unsigned char byte) {
743 char *new_buffer;
744
745
746 if (telnet->buffer_pos == telnet->buffer_size) {
747 size_t i;
748
749 for (i = 0; i != _buffer_sizes_count; ++i) {
750 if (_buffer_sizes[i] == telnet->buffer_size) {
751 break;
752 }
753 }
754
755
756 if (i >= _buffer_sizes_count - 1) {
757 _error(telnet, __LINE__, __func__, TELNET_EOVERFLOW, 0,
758 "subnegotiation buffer size limit reached");
759 return TELNET_EOVERFLOW;
760 }
761
762
763 new_buffer = (char *)realloc(telnet->buffer, _buffer_sizes[i + 1]);
764 if (new_buffer == 0) {
765 _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0,
766 "realloc() failed");
767 return TELNET_ENOMEM;
768 }
769
770 telnet->buffer = new_buffer;
771 telnet->buffer_size = _buffer_sizes[i + 1];
772 }
773
774
775 telnet->buffer[telnet->buffer_pos++] = (char) byte;
776 return TELNET_EOK;
777 }
778
779 static void _process(telnet_t *telnet, const char *buffer, size_t size) {
780 telnet_event_t ev;
781 unsigned char byte;
782 size_t i, start;
783 for (i = start = 0; i != size; ++i) {
784 byte = (unsigned char) buffer[i];
785 switch (telnet->state) {
786
787 case TELNET_STATE_DATA:
788
789
790 if (byte == TELNET_IAC) {
791 if (i != start) {
792 ev.type = TELNET_EV_DATA;
793 ev.data.buffer = buffer + start;
794 ev.data.size = i - start;
795 telnet->eh(telnet, &ev, telnet->ud);
796 }
797 telnet->state = TELNET_STATE_IAC;
798 } else if (byte == '\r' &&
799 (telnet->flags & TELNET_FLAG_NVT_EOL) &&
800 !(telnet->flags & TELNET_FLAG_RECEIVE_BINARY)) {
801 if (i != start) {
802 ev.type = TELNET_EV_DATA;
803 ev.data.buffer = buffer + start;
804 ev.data.size = i - start;
805 telnet->eh(telnet, &ev, telnet->ud);
806 }
807 telnet->state = TELNET_STATE_EOL;
808 }
809 break;
810
811
812 case TELNET_STATE_EOL:
813 if (byte != '\n') {
814 byte = '\r';
815 ev.type = TELNET_EV_DATA;
816 ev.data.buffer = (char*)&byte;
817 ev.data.size = 1;
818 telnet->eh(telnet, &ev, telnet->ud);
819 byte = (unsigned char) buffer[i];
820 }
821
822
823 start = i;
824 if (byte == '\0')
825 ++start;
826
827 telnet->state = TELNET_STATE_DATA;
828 break;
829
830
831 case TELNET_STATE_IAC:
832 switch (byte) {
833
834 case TELNET_SB:
835 telnet->state = TELNET_STATE_SB;
836 break;
837
838 case TELNET_WILL:
839 telnet->state = TELNET_STATE_WILL;
840 break;
841 case TELNET_WONT:
842 telnet->state = TELNET_STATE_WONT;
843 break;
844 case TELNET_DO:
845 telnet->state = TELNET_STATE_DO;
846 break;
847 case TELNET_DONT:
848 telnet->state = TELNET_STATE_DONT;
849 break;
850
851 case TELNET_IAC:
852
853 ev.type = TELNET_EV_DATA;
854 ev.data.buffer = (char*)&byte;
855 ev.data.size = 1;
856 telnet->eh(telnet, &ev, telnet->ud);
857
858
859 start = i + 1;
860 telnet->state = TELNET_STATE_DATA;
861 break;
862
863 default:
864
865 ev.type = TELNET_EV_IAC;
866 ev.iac.cmd = byte;
867 telnet->eh(telnet, &ev, telnet->ud);
868
869
870 start = i + 1;
871 telnet->state = TELNET_STATE_DATA;
872 }
873 break;
874
875
876 case TELNET_STATE_WILL:
877 case TELNET_STATE_WONT:
878 case TELNET_STATE_DO:
879 case TELNET_STATE_DONT:
880 _negotiate(telnet, byte);
881 start = i + 1;
882 telnet->state = TELNET_STATE_DATA;
883 break;
884
885
886 case TELNET_STATE_SB:
887 telnet->sb_telopt = byte;
888 telnet->buffer_pos = 0;
889 telnet->state = TELNET_STATE_SB_DATA;
890 break;
891
892
893 case TELNET_STATE_SB_DATA:
894
895 if (byte == TELNET_IAC) {
896 telnet->state = TELNET_STATE_SB_DATA_IAC;
897 } else if (_buffer_byte(telnet, byte) != TELNET_EOK) {
898 start = i + 1;
899 telnet->state = TELNET_STATE_DATA;
900 }
901 break;
902
903
904 case TELNET_STATE_SB_DATA_IAC:
905 switch (byte) {
906
907 case TELNET_SE:
908
909 start = i + 1;
910 telnet->state = TELNET_STATE_DATA;
911
912
913 if (_subnegotiate(telnet) != 0) {
914 telnet_recv(telnet, &buffer[start], size - start);
915 return;
916 }
917 break;
918
919 case TELNET_IAC:
920
921 if (_buffer_byte(telnet, TELNET_IAC) !=
922 TELNET_EOK) {
923 start = i + 1;
924 telnet->state = TELNET_STATE_DATA;
925 } else {
926 telnet->state = TELNET_STATE_SB_DATA;
927 }
928 break;
929
930
931
932
933
934
935 default:
936 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
937 "unexpected byte after IAC inside SB: %d",
938 byte);
939
940
941 start = i + 1;
942 telnet->state = TELNET_STATE_IAC;
943
944
945
946
947
948
949 if (_subnegotiate(telnet) != 0) {
950 telnet_recv(telnet, &buffer[start], size - start);
951 return;
952 } else {
953
954
955
956
957
958
959
960 _process(telnet, (char *)&byte, 1);
961 }
962 break;
963 }
964 break;
965 }
966 }
967
968
969 if (telnet->state == TELNET_STATE_DATA && i != start) {
970 ev.type = TELNET_EV_DATA;
971 ev.data.buffer = buffer + start;
972 ev.data.size = i - start;
973 telnet->eh(telnet, &ev, telnet->ud);
974 }
975 }
976
977
978 void telnet_recv(telnet_t *telnet, const char *buffer,
979 size_t size) {
980 _process(telnet, buffer, size);
981 }
982
983
984 void telnet_iac(telnet_t *telnet, unsigned char cmd) {
985 unsigned char bytes[2];
986 bytes[0] = TELNET_IAC;
987 bytes[1] = cmd;
988 _sendu(telnet, bytes, 2);
989 }
990
991
992 void telnet_negotiate(telnet_t *telnet, unsigned char cmd,
993 unsigned char telopt) {
994 telnet_rfc1143_t q;
995
996
997 if (telnet->flags & TELNET_FLAG_PROXY) {
998 unsigned char bytes[3];
999 bytes[0] = TELNET_IAC;
1000 bytes[1] = cmd;
1001 bytes[2] = telopt;
1002 _sendu(telnet, bytes, 3);
1003 return;
1004 }
1005
1006
1007 q = _get_rfc1143(telnet, telopt);
1008
1009 switch (cmd) {
1010
1011 case TELNET_WILL:
1012 switch (Q_US(q)) {
1013 case Q_NO:
1014 _set_rfc1143(telnet, telopt, Q_WANTYES, Q_HIM(q));
1015 _send_negotiate(telnet, TELNET_WILL, telopt);
1016 break;
1017 case Q_WANTNO:
1018 _set_rfc1143(telnet, telopt, Q_WANTNO_OP, Q_HIM(q));
1019 break;
1020 case Q_WANTYES_OP:
1021 _set_rfc1143(telnet, telopt, Q_WANTYES, Q_HIM(q));
1022 break;
1023 }
1024 break;
1025
1026
1027 case TELNET_WONT:
1028 switch (Q_US(q)) {
1029 case Q_YES:
1030 _set_rfc1143(telnet, telopt, Q_WANTNO, Q_HIM(q));
1031 _send_negotiate(telnet, TELNET_WONT, telopt);
1032 break;
1033 case Q_WANTYES:
1034 _set_rfc1143(telnet, telopt, Q_WANTYES_OP, Q_HIM(q));
1035 break;
1036 case Q_WANTNO_OP:
1037 _set_rfc1143(telnet, telopt, Q_WANTNO, Q_HIM(q));
1038 break;
1039 }
1040 break;
1041
1042
1043 case TELNET_DO:
1044 switch (Q_HIM(q)) {
1045 case Q_NO:
1046 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES);
1047 _send_negotiate(telnet, TELNET_DO, telopt);
1048 break;
1049 case Q_WANTNO:
1050 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO_OP);
1051 break;
1052 case Q_WANTYES_OP:
1053 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES);
1054 break;
1055 }
1056 break;
1057
1058
1059 case TELNET_DONT:
1060 switch (Q_HIM(q)) {
1061 case Q_YES:
1062 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO);
1063 _send_negotiate(telnet, TELNET_DONT, telopt);
1064 break;
1065 case Q_WANTYES:
1066 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES_OP);
1067 break;
1068 case Q_WANTNO_OP:
1069 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO);
1070 break;
1071 }
1072 break;
1073 }
1074 }
1075
1076
1077 void telnet_send(telnet_t *telnet, const char *buffer,
1078 size_t size) {
1079 size_t i, l;
1080
1081 for (l = i = 0; i != size; ++i) {
1082
1083 if (buffer[i] == (char)TELNET_IAC) {
1084
1085 if (i != l) {
1086 _send(telnet, buffer + l, i - l);
1087 }
1088 l = i + 1;
1089
1090
1091 telnet_iac(telnet, TELNET_IAC);
1092 }
1093 }
1094
1095
1096 if (i != l) {
1097 _send(telnet, buffer + l, i - l);
1098 }
1099 }
1100
1101
1102 void telnet_send_text(telnet_t *telnet, const char *buffer,
1103 size_t size) {
1104 size_t i, l;
1105
1106 for (l = i = 0; i != size; ++i) {
1107
1108 if (buffer[i] == (char)TELNET_IAC) {
1109
1110 if (i != l) {
1111 _send(telnet, buffer + l, i - l);
1112 }
1113 l = i + 1;
1114
1115
1116 telnet_iac(telnet, TELNET_IAC);
1117 }
1118
1119 else if (!(telnet->flags & TELNET_FLAG_TRANSMIT_BINARY) &&
1120 (buffer[i] == '\r' || buffer[i] == '\n')) {
1121
1122 if (i != l) {
1123 _send(telnet, buffer + l, i - l);
1124 }
1125 l = i + 1;
1126
1127
1128 if (buffer[i] == '\r') {
1129 _send(telnet, CRNUL, 2);
1130 }
1131
1132 else {
1133 _send(telnet, CRLF, 2);
1134 }
1135 }
1136 }
1137
1138
1139 if (i != l) {
1140 _send(telnet, buffer + l, i - l);
1141 }
1142 }
1143
1144
1145 void telnet_begin_sb(telnet_t *telnet, unsigned char telopt) {
1146 unsigned char sb[3];
1147 sb[0] = TELNET_IAC;
1148 sb[1] = TELNET_SB;
1149 sb[2] = telopt;
1150 _sendu(telnet, sb, 3);
1151 }
1152
1153
1154 int telnet_vprintf(telnet_t *telnet, const char *fmt, va_list va) {
1155 char buffer[1024];
1156 char *output = buffer;
1157 int rs, i, l;
1158
1159
1160 va_list va2;
1161 va_copy(va2, va);
1162 rs = vsnprintf(buffer, sizeof(buffer), fmt, va);
1163 if ((unsigned long) rs >= sizeof(buffer)) {
1164 output = (char*)malloc((unsigned long) ((unsigned long)rs + 1L));
1165 if (output == 0) {
1166 _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0,
1167 "malloc() failed: %s", strerror(errno));
1168 va_end(va2);
1169 return -1;
1170 }
1171 rs = vsnprintf(output, rs + 1, fmt, va2);
1172 }
1173 va_end(va2);
1174 va_end(va);
1175
1176
1177 for (l = i = 0; i != rs; ++i) {
1178
1179 if (output[i] == (char)TELNET_IAC || output[i] == '\r' ||
1180 output[i] == '\n') {
1181
1182 if (i != l)
1183 _send(telnet, output + l, (size_t) (i - l));
1184 l = i + 1;
1185
1186
1187 if (output[i] == (char)TELNET_IAC)
1188 telnet_iac(telnet, TELNET_IAC);
1189
1190 else if (output[i] == '\r')
1191 _send(telnet, CRNUL, 2);
1192
1193 else if (output[i] == '\n')
1194 _send(telnet, CRLF, 2);
1195 }
1196 }
1197
1198
1199 if (i != l) {
1200 _send(telnet, output + l, (size_t) (i - l));
1201 }
1202
1203
1204 if (output != buffer) {
1205 FREE(output);
1206 }
1207
1208 return rs;
1209 }
1210
1211
1212 int telnet_printf(telnet_t *telnet, const char *fmt, ...) {
1213 va_list va;
1214 int rs;
1215
1216 va_start(va, fmt);
1217 rs = telnet_vprintf(telnet, fmt, va);
1218 va_end(va);
1219
1220 return rs;
1221 }
1222
1223
1224 int telnet_raw_vprintf(telnet_t *telnet, const char *fmt, va_list va) {
1225 char buffer[1024];
1226 char *output = buffer;
1227 int rs;
1228
1229
1230 va_list va2;
1231 va_copy(va2, va);
1232 rs = vsnprintf(buffer, sizeof(buffer), fmt, va);
1233 if ((unsigned long) rs >= sizeof(buffer)) {
1234 output = (char*)malloc((unsigned long) rs + 1);
1235 if (output == 0) {
1236 _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0,
1237 "malloc() failed: %s", strerror(errno));
1238 va_end(va2);
1239 return -1;
1240 }
1241 rs = vsnprintf(output, (int)((unsigned int) rs + 1), fmt, va2);
1242 }
1243 va_end(va2);
1244 va_end(va);
1245
1246
1247 telnet_send(telnet, output, (size_t) rs);
1248
1249
1250 if (output != buffer) {
1251 FREE(output);
1252 }
1253
1254 return rs;
1255 }
1256
1257
1258 int telnet_raw_printf(telnet_t *telnet, const char *fmt, ...) {
1259 va_list va;
1260 int rs;
1261
1262 va_start(va, fmt);
1263 rs = telnet_raw_vprintf(telnet, fmt, va);
1264 va_end(va);
1265
1266 return rs;
1267 }