1 /*
2     Terminal Mixer - multi-point multi-user access to terminal applications
3     Copyright (C) 2007  Lluís Batlle i Rossell
4 
5     Please find the license in the provided COPYING file.
6 */
7 #include <stdlib.h>
8 #include "main.h"
9 #include "filter.h"
10 
11 enum TState
12 {
13     NOTHING,
14     RECEIVED_IAC,
15     RECEIVED_OPT,
16     SUBNEGOTIATED
17 };
18 
19 enum Chars
20 {
21     IAC = 255,
22     SB = 250,
23     SE = 240
24 };
25 
26 struct FTelnet
27 {
28     struct FFilter base;
29     enum TState state;
30 };
31 
ftelnet_reset(struct FFilter * ff)32 static void ftelnet_reset(struct FFilter *ff)
33 {
34     struct FTelnet *ft = (struct FTelnet *) ff;
35     ft->state = NOTHING;
36 }
37 
ftelnet_function(struct FFilter * ff,unsigned char c)38 static int ftelnet_function(struct FFilter *ff, unsigned char c)
39 {
40     struct FTelnet *ft = (struct FTelnet *) ff;
41 
42     switch (ft->state)
43     {
44         case NOTHING:
45             if (c == IAC)
46             {
47                 ft->state = RECEIVED_IAC;
48                 ft->base.matched++;
49             }
50             break;
51         case RECEIVED_IAC:
52             if (c == SB)
53             {
54                 ft->state = SUBNEGOTIATED;
55                 ft->base.matched++;
56             } else /* Received the control char */
57             {
58                 ft->state = RECEIVED_OPT;
59                 ft->base.matched++;
60             }
61             break;
62         case RECEIVED_OPT:
63             ft->base.matched++;
64             return 1;
65             break;
66         case SUBNEGOTIATED:
67             ft->base.matched++;
68             if (c == SE)
69             {
70                 return 1;
71             }
72             break;
73     }
74     return 0;
75 }
76 
new_ftelnet()77 struct FFilter *new_ftelnet()
78 {
79     struct FTelnet *ft;
80     ft = (struct FTelnet *) malloc(sizeof(*ft));
81 
82     ft->state = NOTHING;
83     ft->base.matched = 0;
84     ft->base.function = ftelnet_function;
85     ft->base.reset = ftelnet_reset;
86     ft->base.callback = 0;
87 
88     return (struct FFilter *) ft;
89 }
90