📄 cli_telnet.c
字号:
/************************************************************************
Copyright 200X - 200X+1.
filename : Cli_Telnet.c
description : Telnet主文件
author : Woodhead
modification : Woodhead create 2004-12-07
************************************************************************/
#include "Ros.h"
#include "CLI_Private.inc"
#include "..\include\Cli_Io.h"
#include "Cli_telnet.inc"
#if CLI_DEBUG_ON
_BOOL m_bCliTelnetDebugOn = G_TRUE;
#else
_BOOL m_bCliTelnetDebugOn = G_FALSE;
#endif
/*------------------------------------------------------------------*/
/* Telnet FSM 状态转移表 */
/*------------------------------------------------------------------*/
extern _U32 CLI_CharProcess ( PTerm_Data_S, _U8 ) ;
struct Fsm_Trans_S TTStab[ ] =
{
/*--------------------------------------------------------------*/
/* 当前状态 输入 下一状态 对输入的处理函数 */
/*--------------------------------------------------------------*/
{ TSDATA, TCIAC, TSIAC, CLI_Noop },
{ TSDATA, TCANY, TSDATA, CLI_CharProcess },
{ TSIAC, TCIAC, TSDATA, CLI_CharProcess },
{ TSIAC, TCSB, TSSUBNEG, CLI_Noop },
{ TSIAC, TCNOP, TSDATA, CLI_Noop },
{ TSIAC, TCDM, TSDATA, CLI_tcdm },
{ TSIAC, TCWILL, TSWOPT, CLI_RecOpt },
{ TSIAC, TCWONT, TSWOPT, CLI_RecOpt },
{ TSIAC, TCDO, TSDOPT, CLI_RecOpt },
{ TSIAC, TCDONT, TSDOPT, CLI_RecOpt },
{ TSIAC, TCANY, TSDATA, CLI_Noop },
{ TSSUBNEG, TCIAC, TSSUBIAC, CLI_SubOpt },
{ TSSUBNEG, TCANY, TSSUBNEG, CLI_SubOpt },
{ TSSUBIAC, TCSE, TSDATA, CLI_SubEnd },
{ TSSUBIAC, TCANY, TSSUBNEG, CLI_SubOpt },
{ TSWOPT, TOTERMTYPE, TSDATA, CLI_DoTermType },
{ TSWOPT, TOTXBINARY, TSDATA, CLI_DoTxBinary },
{ TSWOPT, TCANY, TSDATA, CLI_DoNotSup },
{ TSDOPT, TOECHO, TSDATA, CLI_WillEcho },
{ TSDOPT, TONOGA, TSDATA, CLI_WillNoga },
{ TSDOPT, TOTXBINARY, TSDATA, CLI_WillTxBinary},
{ TSDOPT, TCANY, TSDATA, CLI_WillNotSup },
{ FSINVALID,TCANY, FSINVALID, CLI_Abort }
} ;
/*------------------------------------------------------------------*/
/* telnet FSM */
/*------------------------------------------------------------------*/
_U8 TTFsm[ NTSTATES ][ NCHRS ] ;
/*------------------------------------------------------------------*/
/* Telnet选项子协商FSM状态转换表 */
/*------------------------------------------------------------------*/
struct Fsm_Trans_S SubStab[ ] =
{
/*--------------------------------------------------------------*/
/* 当前状态 输入 下一状态 对输入的处理函数 */
/*--------------------------------------------------------------*/
{ SS_START, TOTERMTYPE, SS_TERMTYPE, CLI_Noop },
{ SS_START, TCANY, SS_END, CLI_Noop },
{ SS_TERMTYPE, TT_IS, SS_IS, CLI_Noop },
{ SS_TERMTYPE, TCANY, SS_END, CLI_Noop },
{ SS_IS, TCIAC, SS_END, CLI_SubTermType },
{ SS_IS, TCANY, SS_IS, CLI_SubTermType },
{ SS_END, TCANY, SS_END, CLI_Noop },
{ FSINVALID, TCANY, FSINVALID, CLI_Abort }
} ;
/*------------------------------------------------------------------*/
/* telnet 选项子协商 FSM */
/*------------------------------------------------------------------*/
_U8 SubFsm[ NSSTATES ][ NCHRS ] ;
_S8 szInputChar[ 10 ] ;
/*==================================================================*/
/* 函数名 :CLI_NegotiateOption */
/* 函数功能 :协商telnet选项 */
/* 输入参数 :PTerm_Data_S pTermStruct 任务数据 */
/* 输出参数 :PTerm_Data_S pTermStruct 任务数据 */
/* 返回值 :无 */
/* 调用函数 :CLI_SendToTerm ( ) */
/* 被调函数 : */
/*==================================================================*/
_VOID CLI_NegotiateOption ( PTerm_Data_S pTermStruct )
{
if(pTermStruct == G_NULL)
{
return;
}
/*--------------------------------------------------------------*/
/* 为简单方便, telnet server 仅与telnet client协商以下三个选项: */
/* 1. ECHO */
/* 2. SUPRESS-GO-AHEAD */
/* 3. TERM-TYPE */
/* "IAC WILL ECHO" 设置telnet client远端回显而不本地回显 */
/* "IAC WILL ECHO" and "IAC WILL SUPRESS-GO-AHEAD" 设置client为 */
/* 字符处理设备而非行处理设备 */
/* "IAC DO TERMTYPE" 开始子协商选项 */
/*--------------------------------------------------------------*/
/*--------------------------------------------------------------*/
/* IAC WILL ECHO */
/*--------------------------------------------------------------*/
pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = (_S8)TCIAC ;
pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = (_S8)TCWILL ;
pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = TOECHO ;
/*--------------------------------------------------------------*/
/* IAC WILL SUPRESS-GO-AHEAD */
/*--------------------------------------------------------------*/
pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = (_S8)TCIAC ;
pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = (_S8)TCWILL ;
pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = TONOGA ;
/*--------------------------------------------------------------*/
/* IAC DO TERMTYPE */
/*--------------------------------------------------------------*/
/* 由于在WIN2000下面TELNET慢,所以去掉这里的协商代码 */
#if 0
pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = (_S8)TCIAC ;
pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = (_S8)TCDO ;
pTermStruct->szSendBuf[ pTermStruct->iSendLen++ ] = TOTERMTYPE ;
#endif
pTermStruct->szSendBuf[ pTermStruct->iSendLen ] = '\0' ;
CLI_SendToTerm ( pTermStruct ) ;
return ;
}
/*==================================================================*/
/* 函数名 :CLI_FsmBuild */
/* 函数功能 :建立状态机 */
/* 输入参数 :无 */
/* 输出参数 :无 */
/* 返回值 :无 */
/* 调用函数 :CLI_FsmInit ( ) */
/* 被调函数 : */
/*==================================================================*/
_VOID CLI_FsmBuild ( _VOID )
{
/*--------------------------------------------------------------*/
/* 初始化telnet FSM */
/*--------------------------------------------------------------*/
CLI_FsmInit ( TTFsm, TTStab, NTSTATES ) ;
/*--------------------------------------------------------------*/
/* 初始化选项子协商FSM */
/*--------------------------------------------------------------*/
CLI_FsmInit ( SubFsm, SubStab, NSSTATES ) ;
return ;
}
/*==================================================================*/
/* 函数名 :CLI_FsmInit */
/* 函数功能 :初始化状态机 */
/* 输入参数 :_U8 fsm[ ][ NCHRS ] 要初始化的状态机 */
/* _U8 ucMaxState 最大状态数 */
/* 输出参数 :_U8 fsm[ ][ NCHRS ] 初始化后的状态机 */
/* 返回值 :无 */
/* 调用函数 :CLI_FsmInit ( ) */
/* 被调函数 : */
/*==================================================================*/
_VOID CLI_FsmInit ( _U8 fsm[ ][ NCHRS ],
struct Fsm_Trans_S Ttab[ ],
_U8 ucMaxState )
{
struct Fsm_Trans_S * lpTab ;
_S32 ulState, jState, iChar ;
/*--------------------------------------------------------------*/
/* 首先将FSM初始化为 TINVALID (无效) */
/*--------------------------------------------------------------*/
for ( iChar = 0 ; iChar < NCHRS ; ++ iChar )
for ( ulState = 0 ; ulState < ucMaxState ; ++ ulState )
fsm[ ulState ][ iChar ] = TINVALID ;
/*--------------------------------------------------------------*/
/*根据状态转移表初始化FSM,将FSM与状态转换表对应起来,建立索引关系*/
/*--------------------------------------------------------------*/
for ( ulState = 0 ; Ttab[ ulState ].Ft_State != FSINVALID ; ++ ulState )
{
lpTab = &Ttab[ ulState ] ;
jState = lpTab->Ft_State ;
if ( lpTab->Ft_Char == TCANY )
{
for ( iChar = 0 ; iChar < NCHRS ; ++ iChar )
if ( fsm[ jState ][ iChar ] == TINVALID )
fsm[ jState ][ iChar ] = (_U8)ulState ;
}
else
fsm[ jState ][ lpTab->Ft_Char ] = (_U8)ulState ;
}
return ;
}
/*==================================================================*/
/* 函数名 :CLI_tcdm */
/* 函数功能 :处理telnet "data mark"数据标记信令 */
/* 输入参数 :PTerm_Data_S pTermStruct 任务数据 */
/* _U8 c 接收到的输入字符 */
/* 输出参数 :PTerm_Data_S pTermStruct 任务数据 */
/* 返回值 :_U32 1:成功 */
/* 调用函数 :CLI_DebugOutString ( ) */
/* 被调函数 : */
/*==================================================================*/
_U32 CLI_tcdm ( PTerm_Data_S pTermStruct, _U8 c )
{
_S8 szFSMInfoEn[] =
"\r\n\r\n The telnet NVT FSM : \r\n \
\r\n the current state : TSIAC \
\r\n the input character : DM ( Data Mark ) \
\r\n the next state : TSDATA \
\r\n the action : Synching = 0 ";
_S8 szFSMInfoCh[] =
"\r\n\r\n Telnet 网络虚拟终端状态机 : \r\n \
\r\n 当前状态 : TSIAC \
\r\n 输入字符 : DM ( Data Mark ) \
\r\n 下一状态 : TSDATA \
\r\n 执行动作 : Synching = 0 ";
(_VOID)c ; /* for lint */
if(pTermStruct == G_NULL)
{
return 1;
}
/*--------------------------------------------------------------*/
/* marks end of SYNCH */
/*--------------------------------------------------------------*/
pTermStruct->TelnetParam.Synching = 0 ;
if ( G_TRUE == m_bCliTelnetDebugOn )
{
if ( pTermStruct->iRecvLen == 1 )
{
CLI_TelFSMDegOut(szFSMInfoEn, szFSMInfoCh);
}
}
return 1 ;
}
/*==================================================================*/
/* 函数名 :CLI_RecOpt */
/* 函数功能 :记录选项类型 */
/* 输入参数 :PTerm_Data_S pTermStruct 任务数据 */
/* _U8 c 接收到的输入字符 */
/* 输出参数 :PTerm_Data_S pTermStruct 任务数据 */
/* 返回值 :_U32 1:成功 */
/* 调用函数 :CLI_DebugOutString ( ) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -