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