mirror of
https://github.com/ksherlock/marlene.git
synced 2024-12-21 22:29:28 +00:00
new telnet code.
This commit is contained in:
parent
c956be1319
commit
1380609800
264
telnet.c
Normal file
264
telnet.c
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
/*
|
||||||
|
* This handles telnet "negotiation", etc.
|
||||||
|
* We don't actually negotiate anything but we at least strip
|
||||||
|
* the telnet commands.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma noroot
|
||||||
|
|
||||||
|
#include "telnet.h"
|
||||||
|
|
||||||
|
extern unsigned char buffer[];
|
||||||
|
extern unsigned buffer_size;
|
||||||
|
|
||||||
|
extern void send(const unsigned char *, unsigned);
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
st_data = 0,
|
||||||
|
st_iac,
|
||||||
|
st_do,
|
||||||
|
st_dont,
|
||||||
|
st_will,
|
||||||
|
st_wont,
|
||||||
|
st_sb,
|
||||||
|
st_sb_iac,
|
||||||
|
st_cr
|
||||||
|
};
|
||||||
|
|
||||||
|
static int state = 0;
|
||||||
|
|
||||||
|
static unsigned do_bits[3];
|
||||||
|
static unsigned dont_bits[3];
|
||||||
|
|
||||||
|
static unsigned will_bits[3];
|
||||||
|
static unsigned wont_bits[3];
|
||||||
|
|
||||||
|
#define set_bit(type, x) \
|
||||||
|
type ## _bits[(x) >> 4] |= 1 << ((x) & 0x0f)
|
||||||
|
|
||||||
|
#define has_bit(type, x) \
|
||||||
|
(type ## _bits[(x) >> 4] & 1 << ((x) & 0x0f))
|
||||||
|
|
||||||
|
|
||||||
|
void telnet_init(void) {
|
||||||
|
static unsigned char msg[] = {
|
||||||
|
|
||||||
|
IAC, DO, TELOPT_SGA,
|
||||||
|
IAC, DO, TELOPT_ECHO,
|
||||||
|
IAC, WONT, TELOPT_ECHO,
|
||||||
|
IAC, DO, TELOPT_BINARY,
|
||||||
|
IAC, DONT, TELOPT_LINEMODE,
|
||||||
|
IAC, WILL, TELOPT_TTYPE,
|
||||||
|
IAC, WILL, TELOPT_NAWS,
|
||||||
|
IAC, WILL, TELOPT_TSPEED,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
do_bits[0] = 0;
|
||||||
|
do_bits[1] = 0;
|
||||||
|
do_bits[2] = 0;
|
||||||
|
|
||||||
|
dont_bits[0] = 0;
|
||||||
|
dont_bits[1] = 0;
|
||||||
|
dont_bits[2] = 0;
|
||||||
|
|
||||||
|
will_bits[0] = 0;
|
||||||
|
will_bits[1] = 0;
|
||||||
|
will_bits[2] = 0;
|
||||||
|
|
||||||
|
wont_bits[0] = 0;
|
||||||
|
wont_bits[1] = 0;
|
||||||
|
wont_bits[2] = 0;
|
||||||
|
|
||||||
|
|
||||||
|
state = st_data;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
set_bit(do, TELOPT_SGA);
|
||||||
|
set_bit(do, TELOPT_ECHO);
|
||||||
|
set_bit(do, TELOPT_BINARY);
|
||||||
|
|
||||||
|
set_bit(dont, TELOPT_LINEMODE);
|
||||||
|
|
||||||
|
set_bit(will, TELOPT_TTYPE);
|
||||||
|
set_bit(will, TELOPT_NAWS);
|
||||||
|
set_bit(will, TELOPT_TSPEED);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
send(msg, sizeof(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void telnet_process(void) {
|
||||||
|
|
||||||
|
unsigned i, j;
|
||||||
|
unsigned char cmd[3];
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned char telopt_naws[] = {
|
||||||
|
IAC, SB, TELOPT_NAWS,
|
||||||
|
0, 80, 0, 24,
|
||||||
|
IAC, SE
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char telopt_tspeed[] = {
|
||||||
|
IAC, SB, TELOPT_TSPEED,
|
||||||
|
'9', '6', '0', '0', ',', '9', '6', '0', '0',
|
||||||
|
IAC, SE
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char telopt_ttype[] = {
|
||||||
|
IAC, SB, TELOPT_TTYPE, TELQUAL_IS,
|
||||||
|
'V', 'T', '1', '0', '0',
|
||||||
|
IAC, SE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* don't need to process if no state, no IACs in buffer */
|
||||||
|
if (!state) {
|
||||||
|
/* check for an IAC */
|
||||||
|
for (i = 0; i < buffer_size; ++i) {
|
||||||
|
if (buffer[i] == IAC) break;
|
||||||
|
}
|
||||||
|
if (i == buffer_size) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0, j = 0; i < buffer_size; ++i) {
|
||||||
|
|
||||||
|
unsigned char c = buffer[i];
|
||||||
|
switch(state) {
|
||||||
|
#if 0
|
||||||
|
// ignoring this for now since vt100 ignores 0x00 anyhow.
|
||||||
|
// also, would only run if other IAC detected.
|
||||||
|
case st_cr: // 0x0d 0x00 < drop the 0x00
|
||||||
|
if (c == 0x00) {
|
||||||
|
state = st_data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* drop through */
|
||||||
|
#endif
|
||||||
|
case st_data:
|
||||||
|
if (c == IAC) {
|
||||||
|
state = st_iac;
|
||||||
|
}
|
||||||
|
else buffer[j++] = c;
|
||||||
|
//if (c == 0x0d) state = st_cr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case st_iac:
|
||||||
|
switch (c) {
|
||||||
|
case IAC: // IAC IAC -> IAC
|
||||||
|
state = st_data;
|
||||||
|
buffer[j++] = c;
|
||||||
|
break;
|
||||||
|
case AYT:
|
||||||
|
send("\r\n[Yes]\r\n", 9);
|
||||||
|
state = st_data;
|
||||||
|
break;
|
||||||
|
case DO: state = st_do; break;
|
||||||
|
case DONT: state = st_dont; break;
|
||||||
|
case WILL: state = st_will; break;
|
||||||
|
case WONT: state = st_wont; break;
|
||||||
|
case SB: state = st_sb; break;
|
||||||
|
default: state = st_data; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case st_do:
|
||||||
|
|
||||||
|
cmd[0] = IAC;
|
||||||
|
cmd[1] = WILL;
|
||||||
|
cmd[2] = c;
|
||||||
|
switch(c) {
|
||||||
|
case TELOPT_SGA:
|
||||||
|
case TELOPT_BINARY:
|
||||||
|
// already said will do them, no reply needed.
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TELOPT_NAWS:
|
||||||
|
set_bit(do, TELOPT_NAWS);
|
||||||
|
send(telopt_naws, sizeof(telopt_naws));
|
||||||
|
break;
|
||||||
|
case TELOPT_TSPEED:
|
||||||
|
send(telopt_tspeed, sizeof(telopt_tspeed));
|
||||||
|
break;
|
||||||
|
case TELOPT_TTYPE:
|
||||||
|
send(telopt_ttype, sizeof(telopt_ttype));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case TELOPT_ECHO:
|
||||||
|
cmd[1] = WONT;
|
||||||
|
send(cmd, 3);
|
||||||
|
}
|
||||||
|
state = st_data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case st_dont:
|
||||||
|
cmd[0] = IAC;
|
||||||
|
cmd[1] = WONT;
|
||||||
|
cmd[2] = c;
|
||||||
|
#if 0
|
||||||
|
switch(c) {
|
||||||
|
case TELOPT_SGA:
|
||||||
|
cmd[1] = WILL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
send(cmd, 3);
|
||||||
|
state = st_data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case st_will:
|
||||||
|
cmd[0] = IAC;
|
||||||
|
cmd[1] = DO;
|
||||||
|
cmd[2] = c;
|
||||||
|
switch(c) {
|
||||||
|
case TELOPT_SGA:
|
||||||
|
case TELOPT_BINARY:
|
||||||
|
case TELOPT_ECHO:
|
||||||
|
case TELOPT_NAWS:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cmd[1] = DONT;
|
||||||
|
send(cmd, 3);
|
||||||
|
}
|
||||||
|
state = st_data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case st_wont:
|
||||||
|
#if 0
|
||||||
|
cmd[0] = IAC;
|
||||||
|
cmd[1] = DONT;
|
||||||
|
cmd[2] = c;
|
||||||
|
switch(c) {
|
||||||
|
case TELOPT_SGA:
|
||||||
|
case TELOPT_LINEMODE:
|
||||||
|
cmp[1] = DO;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
send(cmd, 3);
|
||||||
|
#endif
|
||||||
|
state = st_data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case st_sb:
|
||||||
|
|
||||||
|
if (c == IAC) state = st_sb_iac;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case st_sb_iac:
|
||||||
|
// IAC | IAC or IAC | SE
|
||||||
|
if (c == SE) state = st_data;
|
||||||
|
else state = st_sb;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer_size = j;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user