// ProtocolRx.cpp: implementation of the CProtocolRx class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Telnet.h"
#include "

rotocolRx.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
extern HANDLE stdin1;
extern HANDLE stdout1;
extern HANDLE stderr1;
void nvt(SOCKET server,unsigned char data);
enum _ansi_state
{
as_normal,
as_esc,
as_esc1
};
static int sa = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
char codebuf[256];
unsigned char codeptr;
#define NUM_CODEC 6
typedef void (*LPCODEPROC)(char*);
void ansi_set_screen_attribute(char* buffer);
void ansi_set_position(char* buffer);
void ansi_erase_screen(char* buffer);
void ansi_move_up(char* buffer);
void ansi(SOCKET server,unsigned char data);
void ansi_erase_line(char* buffer);
void ddww_error(SOCKET server,_verb verb,_option option);
void ddww_echo(SOCKET server,_verb verb, _option option);
void ddww_supp(SOCKET server,_verb verb,_option option); //Suppress GA
void ddww_term(SOCKET server,_verb verb,_option option); //Subnegotiate terminal type
void sbproc_term(SOCKET server,unsigned char data);
struct
{
unsigned char cmd;
LPCODEPROC proc;
} codec[NUM_CODEC] = {
{'m',ansi_set_screen_attribute},
{'H',ansi_set_position},
{'K',ansi_erase_line},
{'J',ansi_erase_screen},
{'A',ansi_move_up},
{0,0}
};
CProtocolRx::CProtocolRx()
{
}
CProtocolRx::~CProtocolRx()
{
}
#define NUL 0
#define BEL 7
#define BS 8
#define HT 9
#define LF 10
#define VT 11
#define FF 12
#define CR 13
#define SE 240
#define NOP 241
#define DM 242
#define BRK 243
#define IP 244
#define AO 245
#define AYT 246
#define EC 247
#define EL 248
#define GA 249
#define SB 250
#define WILL 251
#define WONT 252
#define DO 253
#define DONT 254
#define IAC 255
int option_error(_verb,_option,int,SOCKET);
typedef void(*LPOPTIONPROC)(SOCKET,_verb,_option);
typedef void(*LPDATAPROC)(SOCKET,unsigned char data);
inline void yesreply(SOCKET server, _verb verb,_option option)
{
unsigned char buf[3];
buf[0] = IAC;
buf[1] = (verb==verb_do)?WILL

verb==verb_dont)?WONT

verb==verb_will)?DO

ONT;
buf[2] = (unsigned char)option;
send(server,(char*)buf,3,0);
}
inline void noreply(SOCKET server, _verb verb,_option option)
{
unsigned char buf[3];
buf[0] = IAC;
buf[1] = (verb==verb_do)?WONT

verb==verb_dont)?WILL

verb==verb_will)?DONT

O;
buf[2] = (unsigned char)option;
send(server,(char*)buf,3,0);
}
inline void askfor(SOCKET server, _verb verb,_option option)
{
unsigned char buf[3];
buf[0] = IAC;
buf[1] = (unsigned char)verb;
buf[2] = (unsigned char)option;
send(server,(char*)buf,3,0);
}
void ddww_error(SOCKET server,_verb verb,_option option)
{
#ifdef _DEBUG
char tmp[256];
wsprintf(tmp,"Unknown Option Code: %s, %i\n",(verb==verb_do)?"DO"

verb==verb_dont)?"DON'T"

verb==verb_will)?"WILL":"WONT",(int)option);
OutputDebugString(tmp);
#endif
switch(verb)
{
case verb_will:
noreply(server,verb,option);
break;
case verb_wont:
return;
case verb_do:
noreply(server,verb,option);
break;
case verb_dont:
return;
}
}
void ddww_echo(SOCKET server,_verb verb, _option option)
{
DWORD mode;
GetConsoleMode(stdin1,&mode); // ENABLE_ECHO_INPUT
int set = !(mode & ENABLE_ECHO_INPUT);
switch(verb)
{
case verb_will: // server wants to echo stuff
if(set) return; //don't confirm - already set.
SetConsoleMode(stdin1,mode & (~ENABLE_ECHO_INPUT));
break;
case verb_wont: // server don't want to echo
if(!set) return; //don't confirm - already unset.
SetConsoleMode(stdin1,mode | ENABLE_ECHO_INPUT);
break;
case verb_do: // server wants me to loopback
noreply(server,verb,option);
return;
case verb_dont: // server doesn't want me to echo
break; // don't bother to reply - I don't
}
yesreply(server,verb,option);
}
void ddww_supp(SOCKET server,_verb verb,_option option) //Suppress GA
{
DWORD mode;
GetConsoleMode(stdin1,&mode); // ENABLE_LINE_INPUT
int set = !(mode & ENABLE_LINE_INPUT);
switch(verb)
{
case verb_will: // server wants to suppress GA's
if(set) break; //don't confirm - already set.
SetConsoleMode(stdin1,mode & (~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)));
askfor(server,verb_do,TOPT_SUPP);
askfor(server,verb_will,TOPT_SUPP);
askfor(server,verb_do,TOPT_ECHO);
break;
case verb_wont: // server wants to send GA's
if(!set) break; //don't confirm - already unset.
SetConsoleMode(stdin1,mode | ENABLE_LINE_INPUT);
askfor(server,verb_dont,TOPT_SUPP);
askfor(server,verb_wont,TOPT_SUPP);
break;
case verb_do: // server wants me to suppress GA's
if(set) break;
askfor(server,verb_do,TOPT_SUPP);
break;
case verb_dont: // server wants me to send GA's
if(!set) break;
askfor(server,verb_dont,TOPT_SUPP);
break;
}
}
///////////////////////////////////////////////////////////////////////////////
// Option TERMINAL-TYPE
void ddww_term(SOCKET server,_verb verb,_option option) //Subnegotiate terminal type
{
switch(verb)
{
case verb_will:
noreply(server,verb,option); // I don't want terminal info
break;
case verb_wont:
//dat be cool - its not going to send. no need to confirm
break;
case verb_do:
yesreply(server,verb,option); //I'll send it when asked
break;
case verb_dont://Ok - I won't
break;
}
}
// TERMINAL TYPE subnegotation
enum
{
SB_TERM_IS = 0,
SB_TERM_SEND = 1
};
#define NUM_TERMINALS 2
struct
{
char* name;
LPDATAPROC termproc;
//pre requsites.
} terminal[NUM_TERMINALS] = {
{ "NVT", nvt },
{ "ANSI", ansi }
};
int term_index = 0;
void sbproc_term(SOCKET server,unsigned char data)
{
if(data == SB_TERM_SEND)
{
if(term_index == NUM_TERMINALS)
term_index = 0;
else
term_index++;
char buf[16]; //pls limit
buf[0] = IAC;
buf[1] = SB;
buf[2] = TOPT_TERM;
buf[3] = SB_TERM_IS;
lstrcpy(&buf[4],terminal[(term_index==NUM_TERMINALS)?(NUM_TERMINALS-1):term_index].name);
int nlen = lstrlen(&buf[4]);
buf[4+nlen] = IAC;
buf[5+nlen] = SE;
send(server,buf,4+nlen+2,0);
}
}
///////////////////////////////////////////////////////////////////////////////
struct
{
_option option;
LPOPTIONPROC OptionProc;
LPDATAPROC DataProc;
} ol[] = {
{TOPT_ECHO, ddww_echo, NULL},
{TOPT_SUPP, ddww_supp, NULL},
{TOPT_TERM, ddww_term, sbproc_term},
{TOPT_ERROR, ddww_error, NULL}
};