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