ProtocolRx.cpp
上传用户:yuanwufei9
上传日期:2007-01-09
资源大小:21k
文件大小:13k
- // ProtocolRx.cpp: implementation of the CProtocolRx class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "Telnet.h"
- #include "ProtocolRx.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 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:DONT;
- 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:DO;
- 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, %in",(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}
- };
- void CProtocolRx::TelentProtcol(SOCKET server,unsigned char code)
- {
- //These vars are the finite state
- static int state = state_data;
- static _verb verb = verb_sb;
- static LPDATAPROC DataProc = terminal[(term_index==NUM_TERMINALS)?(NUM_TERMINALS-1):term_index].termproc;
- //Decide what to do (state based)
- switch(state)
- {
- case state_data:
- switch(code)
- {
- case IAC: state = state_code; break;
- default: DataProc(server,code);
- }
- break;
- case state_code:
- state = state_data;
- switch(code)
- {
- // State transition back to data
- case IAC:
- DataProc(server,code);
- break;
- // Code state transitions back to data
- case SE:
- DataProc = terminal[(term_index==NUM_TERMINALS)?(NUM_TERMINALS-1):term_index].termproc;
- break;
- case NOP:
- break;
- case DM:
- break;
- case BRK:
- break;
- case IP:
- break;
- case AO:
- break;
- case AYT:
- break;
- case EC:
- break;
- case EL:
- break;
- case GA:
- break;
- // Transitions to option state
- case SB:
- verb = verb_sb;
- state = state_option;
- break;
- case WILL:
- verb = verb_will;
- state = state_option;
- break;
- case WONT:
- verb = verb_wont;
- state = state_option;
- break;
- case DO:
- verb = verb_do;
- state = state_option;
- break;
- case DONT:
- verb = verb_dont;
- state = state_option;
- break;
- }
- break;
- case state_option:
- state = state_data;
- //Find the option entry
- for(
- int i = 0;
- ol[i].option != TOPT_ERROR && ol[i].option != code;
- i++);
- //Do some verb specific stuff
- if(verb == verb_sb)
- DataProc = ol[i].DataProc;
- else
- ol[i].OptionProc(server,verb,(_option)code);
- break;
- }
- }
- void nvt(SOCKET server,unsigned char data)
- {
- DWORD z;
- switch(data)
- {
- case 0: //eat null codes.
- break;
- default: //Send all else to the console.
- WriteConsole(stdout1,&data,1,&z,NULL);
- break;
- }
- }
- void ansi_set_screen_attribute(char* buffer)
- {
- while(*buffer)
- {
- switch(*buffer++)
- {
- case '0': //Normal
- sa = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
- break;
- case '1': //Hign Intensity
- sa |= FOREGROUND_INTENSITY;
- break;
- case '4': //Underscore
- break;
- case '5': //Blink.
- sa |= BACKGROUND_INTENSITY;
- break;
- case '7':
- sa = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE;
- break;
- case '8':
- sa = 0;
- break;
- case '3':
- sa = sa & (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY) |
- (*buffer & 1)?FOREGROUND_RED:0 |
- (*buffer & 2)?FOREGROUND_GREEN:0 |
- (*buffer & 4)?FOREGROUND_BLUE:0;
- if(*buffer)
- buffer++;
- break;
- case '6':
- sa = sa & (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY) |
- (*buffer & 1)?BACKGROUND_RED:0 |
- (*buffer & 2)?BACKGROUND_GREEN:0 |
- (*buffer & 4)?BACKGROUND_BLUE:0;
- if(*buffer)
- buffer++;
- break;
- }
- if(*buffer && *buffer == ';')
- buffer++;
- }
- SetConsoleTextAttribute(stdout1,sa);
- }
- void ansi_erase_line(char* buffer)
- {
- int act = 0;
- while(*buffer)
- {
- act = (*buffer++) - '0';
- }
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- GetConsoleScreenBufferInfo(stdout1,&csbi);
- COORD pos;
- DWORD n;
- switch(act)
- {
- case 0: //erase to end of line
- pos.X = csbi.dwCursorPosition.X;
- pos.Y = csbi.dwCursorPosition.Y;
- n = csbi.dwSize.X - csbi.dwCursorPosition.X;
- break;
- case 1: //erase from beginning
- pos.X = 0;
- pos.Y = csbi.dwCursorPosition.Y;
- n = csbi.dwCursorPosition.X;
- break;
- case 2: // erase whole line
- pos.X = 0;
- pos.Y = csbi.dwCursorPosition.Y;
- n = csbi.dwSize.X;
- break;
- }
- DWORD w;
- FillConsoleOutputCharacter(stdout1,' ',n,pos,&w);
- }
- void ansi_set_position(char* buffer)
- {
- COORD pos = {0,0};
- // Grab line
- while(*buffer && *buffer != ';')
- pos.Y = pos.Y*10 + *buffer++ - '0';
- if(*buffer)
- buffer++;
- // Grab y
- while(*buffer && *buffer != ';')
- pos.X = pos.X*10 + *buffer++ - '0';
- (pos.X)?pos.X--:0;
- (pos.Y)?pos.Y--:0;
- SetConsoleCursorPosition(stdout1,pos);
-
- }
- void ansi_erase_screen(char* buffer)
- {
- int act = 0;
- while(*buffer)
- {
- act = (*buffer++) - '0';
- }
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- GetConsoleScreenBufferInfo(stdout1,&csbi);
- COORD pos;
- DWORD n;
- switch(act)
- {
- case 0:
- pos.X = csbi.dwCursorPosition.X;
- pos.Y = csbi.dwCursorPosition.Y;
- n = csbi.dwSize.X*csbi.dwSize.Y;
- break;
- case 2:
- pos.X = 0;
- pos.Y = 0;
- n = csbi.dwSize.X*csbi.dwSize.Y;
- break;
- }
- DWORD w;
- FillConsoleOutputCharacter(stdout1,' ',n,pos,&w);
- SetConsoleCursorPosition(stdout1,pos);
- }
- void ansi_move_up(char* buffer)
- {
- int cnt = *buffer?0:1;
- while(*buffer)
- {
- cnt = cnt*10 + (*buffer++) - '0';
- }
- COORD pos;
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- GetConsoleScreenBufferInfo(stdout1,&csbi);
- pos.X = csbi.dwCursorPosition.X;
- pos.Y = ((csbi.dwCursorPosition.Y-cnt)>=0)?(csbi.dwCursorPosition.Y-cnt):0;
- SetConsoleCursorPosition(stdout1,pos);
- }
- void ansi(SOCKET server,unsigned char data)
- {
- static _ansi_state state = as_normal;
- DWORD z;
- switch( state)
- {
- case as_normal:
- switch(data)
- {
- case 0: //eat null codes.
- break;
- case 27: //ANSI esc.
- state = as_esc;
- break;
- default: //Send all else to the console.
- WriteConsole(stdout1,&data,1,&z,NULL);
- break;
- }
- break;
- case as_esc:
- state = as_esc1;
- codeptr=0;
- codebuf[codeptr] = 0;
- break;
- case as_esc1:
- if(data > 64)
- {
- codebuf[codeptr] = 0;
- for(int i=0; codec[i].cmd && codec[i].cmd != data; i++);
- if(codec[i].proc)
- codec[i].proc(codebuf);
- #ifdef _DEBUG
- else
- {
- char buf[256];
- wsprintf(buf,"Unknown Ansi code:'%c' (%s)n",data,codebuf);
- OutputDebugString(buf);
- }
- #endif
- state = as_normal;
- }
- else
- codebuf[codeptr++] = data;
- break;
- }
- }