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