📄 telnet.cpp
字号:
// Implementation of the Telnet class
#include "telnet.h"
#include "Socket.h"
#include "SocketException.h"
typedef void(*LPCODEPROC) (char*);
typedef void(*LPOPTIONPROC) (const Telnet &,_verb,_option);
typedef int(*LPDATAPROC) (const Telnet &,unsigned char data);
//typedef int(*LPPROC) (Telnet &,unsigned char data);
const static int NUM_CODEC =6;
void ddww_error(Telnet const&,_verb verb,_option option);
void ddww_echo(Telnet const&,_verb verb, _option option);
void ddww_supp(Telnet const&,_verb verb,_option option); //Suppress GA
void ddww_term(Telnet const&,_verb verb,_option option); //Subnegotiate terminal type
int nvt(const Telnet&,unsigned char data);
int ansi(const Telnet&,unsigned char data);
int sbproc_term(const Telnet &,unsigned char data);
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_erase_line(char* buffer);
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}
};
Telnet::Telnet ( std::string host, int port )
{
/*
codec = {
{'m',ansi_set_screen_attribute},
{'H',ansi_set_position},
{'K',ansi_erase_line},
{'J',ansi_erase_screen},
{'A',ansi_move_up},
{0,0}
};
codec[0].cmd = 'm';
codec[0].proc = ansi_set_screen_attribute;
codec[1].cmd = 'H';
codec[1].proc = ansi_set_position;
codec[2].cmd = 'K';
codec[2].proc = ansi_erase_line;
codec[3].cmd = 'J';
codec[3].proc = ansi_erase_screen;
codec[4].cmd = 'A';
codec[4].proc = ansi_move_up;
codec[5].cmd = 0;
codec[5].proc = 0;
*/
sHost=host;
iPort=port;
if ( ! Socket::create() )
{
throw SocketException ( "Could not create client socket." );
}
/*
if ( ! Socket::connect ( host, port ) )
{
throw SocketException ( "Could not bind to port." );
}
Socket::set_non_blocking ( 1 );
*/
}
int Telnet::Connect ( void )
{
if ( ! Socket::connect ( sHost, iPort ) )
{
throw SocketException ( "Could not bind to port." );
}
Socket::set_non_blocking ( 1 );
return 0;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//int nvt(unsigned char data);
enum _ansi_state
{
as_normal,
as_esc,
as_esc1
};
char codebuf[256];
unsigned char codeptr;
//static unsigned long sa = COLOR_WHITE;
#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,int);
void Telnet::yesreply(_verb verb,_option option) const
{
unsigned char buf[3];
buf[0] = IAC;
buf[1] = (verb==verb_do)?WILL:(verb==verb_dont)?WONT:(verb==verb_will)?DO:DONT;
buf[2] = (unsigned char)option;
Socket::send((char*)buf,3);
}
void Telnet::noreply(_verb verb,_option option) const
{
unsigned char buf[3];
buf[0] = IAC;
buf[1] = (verb==verb_do)?WONT:(verb==verb_dont)?WILL:(verb==verb_will)?DONT:DO;
buf[2] = (unsigned char)option;
Socket::send((char*)buf,3);
}
void Telnet::askfor(_verb verb,_option option) const
{
unsigned char buf[3];
buf[0] = IAC;
buf[1] = (unsigned char)verb;
buf[2] = (unsigned char)option;
Socket::send((char*)buf,3);
}
void ddww_error(Telnet const &t,_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:
t.noreply(verb,option);
break;
case verb_wont:
return;
case verb_do:
t.noreply(verb,option);
break;
case verb_dont:
return;
}
}
void ddww_echo(Telnet const &t,_verb verb, _option option)
{
int mode;
// GetConsoleMode(stdin1,&mode); // ENABLE_ECHO_INPUT
// int set = !(mode & ENABLE_ECHO_INPUT);
int set = !(mode & 0xFF);
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
t.noreply(verb,option);
return;
case verb_dont: // server doesn't want me to echo
break; // don't bother to reply - I don't
}
t.yesreply(verb,option);
}
void ddww_supp(Telnet const &t,_verb verb,_option option) //Suppress GA
{
unsigned long mode;
// GetConsoleMode(stdin1,&mode); // ENABLE_LINE_INPUT
// int set = !(mode & ENABLE_LINE_INPUT);
int set = !(mode & 0xFF);
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)));
t.askfor(verb_do,TOPT_SUPP);
t.askfor(verb_will,TOPT_SUPP);
t.askfor(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);
t.askfor(verb_dont,TOPT_SUPP);
t.askfor(verb_wont,TOPT_SUPP);
break;
case verb_do: // server wants me to suppress GA's
if(set) break;
t.askfor(verb_do,TOPT_SUPP);
break;
case verb_dont: // server wants me to send GA's
if(!set) break;
t.askfor(verb_dont,TOPT_SUPP);
break;
}
}
///////////////////////////////////////////////////////////////////////////////
// Option TERMINAL-TYPE
void ddww_term(Telnet const &t,_verb verb,_option option) //Subnegotiate terminal type
{
switch(verb)
{
case verb_will:
t.noreply(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:
t.yesreply(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 Telnet::termreply(unsigned char data) const
{
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;
strcpy(&buf[4],terminal[(term_index==NUM_TERMINALS)?(NUM_TERMINALS-1):term_index].name);
int nlen = strlen(&buf[4]);
buf[4+nlen] = IAC;
buf[5+nlen] = SE;
Socket::send(buf,4+nlen+2);
}
}
int sbproc_term(Telnet const &t,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;
strcpy(&buf[4],terminal[(term_index==NUM_TERMINALS)?(NUM_TERMINALS-1):term_index].name);
int nlen = strlen(&buf[4]);
buf[4+nlen] = IAC;
buf[5+nlen] = SE;
Socket::send(buf,4+nlen+2);
}
*/
t.termreply(data);
return 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}
};
const int Telnet::TelentProtcol(unsigned char code) const
{
//These vars are the finite state
static int state = state_data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -