mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
581 lines
11 KiB
581 lines
11 KiB
/* File: D:\WACKER\comwsock\comnvt.c (Created: 14-Feb-1996)
|
|
*
|
|
* Copyright 1996 by Hilgraeve Inc. -- Monroe, MI
|
|
* All rights reserved
|
|
*
|
|
* $Revision: 1.4 $
|
|
* $Date: 1996/06/07 16:04:06 $
|
|
*/
|
|
|
|
|
|
//#define DEBUGSTR
|
|
|
|
#include <windows.h>
|
|
#pragma hdrstop
|
|
|
|
#include <tdll\stdtyp.h>
|
|
|
|
#if defined (INCL_WINSOCK)
|
|
|
|
#include <tdll\session.h>
|
|
//#include <tdll\mc.h>
|
|
#include <tdll\com.h>
|
|
#include <tdll\comdev.h>
|
|
#include <comstd\comstd.hh>
|
|
#include "comwsock.hh"
|
|
#include <tdll\assert.h>
|
|
#include <tdll\tchar.h>
|
|
#include <emu\emu.h>
|
|
//include <tdll\com.hh>
|
|
|
|
|
|
// This is the "Network Virtual Terminal" emulation, i.e., the code
|
|
// that handles Telnet option negotiations. WinSockNetworkVirtualTerminal
|
|
// is called to check incoming data to see if there is
|
|
// a Telnet command in there.
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* WinSockCreateNVT
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called to create the necessary hooks and stuff to create
|
|
* a Telnet NVT(network virtual terminal).
|
|
*
|
|
* PARAMETERS:
|
|
* hhDriver -- private connection handle
|
|
*
|
|
* RETURNS:
|
|
* Nothing.
|
|
*
|
|
* AUTHOR
|
|
* mcc 01/09/96 (Ported from NPORT)
|
|
*/
|
|
VOID WinSockCreateNVT(ST_STDCOM * hhDriver)
|
|
{
|
|
|
|
hhDriver->NVTstate = NVT_THRU;
|
|
|
|
hhDriver->stMode[ECHO_MODE].option = TELOPT_ECHO;
|
|
hhDriver->stMode[ECHO_MODE].us = NO;
|
|
hhDriver->stMode[ECHO_MODE].usq = EMPTY;
|
|
hhDriver->stMode[ECHO_MODE].him = NO;
|
|
hhDriver->stMode[ECHO_MODE].himq = EMPTY;
|
|
|
|
hhDriver->stMode[SGA_MODE].option = TELOPT_SGA;
|
|
hhDriver->stMode[SGA_MODE].us = NO;
|
|
hhDriver->stMode[SGA_MODE].usq = EMPTY;
|
|
hhDriver->stMode[SGA_MODE].him = NO;
|
|
hhDriver->stMode[SGA_MODE].himq = EMPTY;
|
|
|
|
hhDriver->stMode[TTYPE_MODE].option = TELOPT_TTYPE;
|
|
hhDriver->stMode[TTYPE_MODE].us = NO;
|
|
hhDriver->stMode[TTYPE_MODE].usq = EMPTY;
|
|
hhDriver->stMode[TTYPE_MODE].him = NO;
|
|
hhDriver->stMode[TTYPE_MODE].himq = EMPTY;
|
|
|
|
hhDriver->stMode[BINARY_MODE].option = TELOPT_BINARY;
|
|
hhDriver->stMode[BINARY_MODE].us = NO;
|
|
hhDriver->stMode[BINARY_MODE].usq = EMPTY;
|
|
hhDriver->stMode[BINARY_MODE].him = NO;
|
|
hhDriver->stMode[BINARY_MODE].himq = EMPTY;
|
|
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* WinSockReleaseNVT
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is currently a stub
|
|
*
|
|
* PARAMETERS:
|
|
* hhDriver -- private connection handle
|
|
*
|
|
* RETURNS:
|
|
* Nothing.
|
|
*/
|
|
VOID WinSockReleaseNVT(ST_STDCOM * hhDriver)
|
|
{
|
|
|
|
DbgOutStr("WS releaseNVT\r\n", 0,0,0,0,0);
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* WinSockGotDO
|
|
*
|
|
* DESCRIPTION:
|
|
* Handles the case of us agreeing that the other side should enable an option
|
|
*
|
|
* PARAMETERS:
|
|
* hhDriver -- private handle for this connection driver
|
|
* pstO -- Telnet options data structure
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*
|
|
* AUTHOR:
|
|
* mcc 01/09/96 (Ported from NPORT)
|
|
*/
|
|
VOID WinSockGotDO (ST_STDCOM * hhDriver, const PSTOPT pstO)
|
|
{
|
|
|
|
DbgOutStr("Got DO: %lx", pstO->him, 0,0,0,0);
|
|
switch (pstO->us)
|
|
{
|
|
case NO:
|
|
#if FALSE // DEADWOOD 11/21/95
|
|
if (TRUE)
|
|
{
|
|
pstO->us = YES;
|
|
WinSockSendMessage(hhDriver, WILL, pstO->option);
|
|
}
|
|
else
|
|
{
|
|
WinSockSendMessage(hhDriver, WONT, pstO->option);
|
|
}
|
|
#else
|
|
pstO->us = YES;
|
|
WinSockSendMessage(hhDriver, WILL, pstO->option);
|
|
#endif
|
|
break;
|
|
|
|
case YES:
|
|
/* Ignore */
|
|
break;
|
|
|
|
case WANTNO:
|
|
if (pstO->usq == EMPTY)
|
|
pstO->us = NO;
|
|
else if (pstO->usq == OPPOSITE)
|
|
pstO->us = YES;
|
|
pstO->usq = EMPTY;
|
|
break;
|
|
|
|
case WANTYES:
|
|
if (pstO->usq == EMPTY)
|
|
{
|
|
pstO->us = YES;
|
|
}
|
|
else if (pstO->usq == OPPOSITE)
|
|
{
|
|
pstO->us = WANTNO;
|
|
pstO->usq = EMPTY;
|
|
WinSockSendMessage(hhDriver, WONT, pstO->option);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* WinSockGotWILL
|
|
*
|
|
* DESCRIPTION:
|
|
* Handles the case of getting a WILL response from the remote Telnet,
|
|
* indicating that an option will be enabled
|
|
*
|
|
* PARAMETERS:
|
|
* hhDriver -- private handle for this connection driver
|
|
* pstO -- Telnet options data structure
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*
|
|
* AUTHOR:
|
|
* mcc 01/09/96 (Ported from NPORT)
|
|
*/
|
|
VOID WinSockGotWILL(ST_STDCOM * hhDriver, const PSTOPT pstO)
|
|
{
|
|
|
|
DbgOutStr("Got WILL: %lx", pstO->him, 0,0,0,0);
|
|
switch(pstO->him)
|
|
{
|
|
case NO:
|
|
#if FALSE //DEADWOOD 11/21/95
|
|
if (TRUE)
|
|
{
|
|
pstO->him = YES;
|
|
WinSockSendMessage(hhDriver, DO, pstO->option);
|
|
}
|
|
else
|
|
{
|
|
WinSockSendMessage(hhDriver, DONT, pstO->option);
|
|
}
|
|
#else
|
|
pstO->him = YES;
|
|
WinSockSendMessage(hhDriver, DO, pstO->option);
|
|
#endif
|
|
break;
|
|
case YES:
|
|
/* Do nothing */
|
|
break;
|
|
case WANTNO:
|
|
if (pstO->himq == EMPTY)
|
|
pstO->him = NO;
|
|
else if (pstO->himq == OPPOSITE)
|
|
pstO->him = YES;
|
|
pstO->himq = EMPTY;
|
|
break;
|
|
case WANTYES:
|
|
if (pstO->himq == EMPTY)
|
|
{
|
|
pstO->him = YES;
|
|
}
|
|
else if (pstO->himq == OPPOSITE)
|
|
{
|
|
pstO->him = WANTNO;
|
|
pstO->himq = EMPTY;
|
|
WinSockSendMessage(hhDriver, DONT, pstO->option);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* WinSockGotDONT
|
|
*
|
|
* DESCRIPTION:
|
|
* Handles the case of getting a DONT option from the remote Telnet,
|
|
* indicating a request not to implement a particular option
|
|
*
|
|
* PARAMETERS:
|
|
* hhDriver Private driver handle
|
|
* pstO
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
VOID WinSockGotDONT(ST_STDCOM * hhDriver, const PSTOPT pstO)
|
|
{
|
|
|
|
DbgOutStr("Got DONT: %lx", pstO->him, 0,0,0,0);
|
|
switch (pstO->us)
|
|
{
|
|
case NO:
|
|
/* Ignore */
|
|
break;
|
|
|
|
case YES:
|
|
pstO->us = NO;
|
|
WinSockSendMessage(hhDriver, WONT, pstO->option);
|
|
break;
|
|
|
|
case WANTNO:
|
|
if (pstO->usq == EMPTY)
|
|
{
|
|
pstO->us = NO;
|
|
}
|
|
else if (pstO->usq == OPPOSITE)
|
|
{
|
|
pstO->us = WANTYES;
|
|
pstO->usq = NONE;
|
|
WinSockSendMessage(hhDriver, WILL, pstO->option);
|
|
}
|
|
break;
|
|
|
|
case WANTYES:
|
|
if (pstO->usq == EMPTY)
|
|
{
|
|
pstO->us = NO;
|
|
}
|
|
else if (pstO->usq == OPPOSITE)
|
|
{
|
|
pstO->us = NO;
|
|
pstO->usq = OPPOSITE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* PARAMETERS:
|
|
*
|
|
* RETURNS:
|
|
*/
|
|
VOID WinSockGotWONT(ST_STDCOM * hhDriver, const PSTOPT pstO)
|
|
{
|
|
DbgOutStr("Got WONT: %lx", pstO->him, 0,0,0,0);
|
|
switch (pstO->him)
|
|
{
|
|
case NO:
|
|
/* Ignore */
|
|
break;
|
|
|
|
case YES:
|
|
pstO->him = NO;
|
|
WinSockSendMessage(hhDriver, DONT, pstO->option);
|
|
break;
|
|
|
|
case WANTNO:
|
|
if (pstO->himq == EMPTY)
|
|
{
|
|
pstO->him = NO;
|
|
}
|
|
else if (pstO->himq == OPPOSITE)
|
|
{
|
|
pstO->him = WANTYES;
|
|
pstO->himq = NONE;
|
|
WinSockSendMessage(hhDriver, DO, pstO->option);
|
|
}
|
|
break;
|
|
|
|
case WANTYES:
|
|
if (pstO->himq == EMPTY)
|
|
{
|
|
pstO->him = NO;
|
|
}
|
|
else if (pstO->himq == OPPOSITE)
|
|
{
|
|
pstO->him = NO;
|
|
pstO->himq = OPPOSITE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* WinSockNetworkVirtualTerminal
|
|
*
|
|
* DESCRIPTION:
|
|
* called from CLoop to handle Telnet option negotiation
|
|
*
|
|
* PARAMETERS:
|
|
* mc The current character being processed
|
|
* pD Pointer to Winsock connection driver private handle
|
|
*
|
|
* RETURNS:
|
|
* NVT_DISCARD if mc is to be discarded
|
|
* NVT_KEEP if mc is to be processed further
|
|
*
|
|
* AUTHOR
|
|
* mcc 01/09/96 (mostly from NPORT)
|
|
*/
|
|
int FAR PASCAL WinSockNetworkVirtualTerminal(ECHAR mc, void *pD)
|
|
{
|
|
ST_STDCOM * hhDriver = (ST_STDCOM *)pD;
|
|
int i;
|
|
int n;
|
|
int nTtype;
|
|
LPSTR pszPtr;
|
|
UCHAR acTerm[64];
|
|
HEMU hEmu;
|
|
HSESSION hSession;
|
|
|
|
assert(hhDriver);
|
|
|
|
//DbgOutStr("NVT %d %c(0x%x = %d)\n", hhDriver->NVTstate,
|
|
// ((mc == 0)? ' ': mc), mc, mc,0);
|
|
|
|
switch (hhDriver->NVTstate)
|
|
{
|
|
case NVT_THRU:
|
|
if (mc == IAC)
|
|
{
|
|
hhDriver->NVTstate = NVT_IAC;
|
|
return NVT_DISCARD ;
|
|
}
|
|
return NVT_KEEP ;
|
|
|
|
case NVT_IAC:
|
|
switch (mc)
|
|
{
|
|
case IAC:
|
|
hhDriver->NVTstate = NVT_THRU; // We really want to send the IAC !
|
|
return NVT_KEEP ;
|
|
case DONT:
|
|
hhDriver->NVTstate = NVT_DONT;
|
|
return NVT_DISCARD ;
|
|
case DO:
|
|
hhDriver->NVTstate = NVT_DO;
|
|
return NVT_DISCARD ;
|
|
case WONT:
|
|
hhDriver->NVTstate = NVT_WONT;
|
|
return NVT_DISCARD ;
|
|
case WILL:
|
|
hhDriver->NVTstate = NVT_WILL;
|
|
return NVT_DISCARD ;
|
|
case SB:
|
|
hhDriver->NVTstate = NVT_SB;
|
|
return NVT_DISCARD ;
|
|
case GA:
|
|
case EL:
|
|
case EC:
|
|
case AYT:
|
|
case AO:
|
|
case IP:
|
|
case BREAK:
|
|
case DM:
|
|
case SE:
|
|
//MessageBeep((UINT)-1);
|
|
hhDriver->NVTstate = NVT_WILL;
|
|
return NVT_DISCARD ;
|
|
case NOP:
|
|
default:
|
|
hhDriver->NVTstate = NVT_THRU;
|
|
return NVT_KEEP;
|
|
}
|
|
|
|
case NVT_WILL:
|
|
for (i = 0; i < MODE_MAX; i++)
|
|
if (hhDriver->stMode[i].option == mc)
|
|
WinSockGotWILL(hhDriver, &hhDriver->stMode[i]);
|
|
|
|
hhDriver->NVTstate = NVT_THRU;
|
|
return NVT_DISCARD ;
|
|
|
|
case NVT_WONT:
|
|
for (i = 0; i < MODE_MAX; i++)
|
|
if (hhDriver->stMode[i].option == mc)
|
|
WinSockGotWONT(hhDriver, &hhDriver->stMode[i]);
|
|
|
|
hhDriver->NVTstate = NVT_THRU;
|
|
return NVT_DISCARD ;
|
|
|
|
case NVT_DO:
|
|
n = 0;
|
|
|
|
for (i = 0; i < MODE_MAX; i++)
|
|
if (hhDriver->stMode[i].option == mc)
|
|
{
|
|
WinSockGotDO(hhDriver, &hhDriver->stMode[i]);
|
|
n = 1;
|
|
}
|
|
|
|
if (n == 0)
|
|
WinSockSendMessage(hhDriver, WONT, mc);
|
|
hhDriver->NVTstate = NVT_THRU;
|
|
return NVT_DISCARD ;
|
|
|
|
case NVT_DONT:
|
|
n = 0;
|
|
|
|
for (i = 0; i < MODE_MAX; i++)
|
|
if (hhDriver->stMode[i].option == mc)
|
|
{
|
|
WinSockGotDONT(hhDriver, &hhDriver->stMode[i]);
|
|
n = 1;
|
|
}
|
|
|
|
if (n == 0)
|
|
WinSockSendMessage(hhDriver, WONT, mc);
|
|
hhDriver->NVTstate = NVT_THRU;
|
|
return NVT_DISCARD ;
|
|
|
|
case NVT_SB:
|
|
/* At this time we only handle one sub-negotiation */
|
|
switch (mc)
|
|
{
|
|
case TELOPT_TTYPE:
|
|
hhDriver->NVTstate = NVT_SB_TT;
|
|
return NVT_DISCARD ;
|
|
default:
|
|
break;
|
|
}
|
|
hhDriver->NVTstate = NVT_THRU;
|
|
return NVT_KEEP;
|
|
|
|
case NVT_SB_TT:
|
|
switch (mc)
|
|
{
|
|
case TELQUAL_SEND:
|
|
hhDriver->NVTstate = NVT_SB_TT_S;
|
|
return NVT_DISCARD ;
|
|
default:
|
|
break;
|
|
}
|
|
hhDriver->NVTstate = NVT_THRU;
|
|
return NVT_KEEP;
|
|
|
|
case NVT_SB_TT_S:
|
|
switch (mc)
|
|
{
|
|
case IAC:
|
|
hhDriver->NVTstate = NVT_SB_TT_S_I;
|
|
return NVT_DISCARD ;
|
|
default:
|
|
break;
|
|
}
|
|
hhDriver->NVTstate = NVT_THRU;
|
|
return NVT_KEEP;
|
|
|
|
case NVT_SB_TT_S_I:
|
|
switch (mc)
|
|
{
|
|
case SE:
|
|
memset(acTerm, 0, sizeof(acTerm));
|
|
pszPtr = (LPSTR)acTerm;
|
|
*pszPtr++ = (UCHAR)IAC;
|
|
*pszPtr++ = (UCHAR)SB;
|
|
*pszPtr++ = (UCHAR)TELOPT_TTYPE;
|
|
*pszPtr++ = (UCHAR)TELQUAL_IS;
|
|
|
|
ComGetSession(hhDriver->hCom, &hSession);
|
|
assert(hSession);
|
|
|
|
hEmu = sessQueryEmuHdl(hSession);
|
|
assert(hEmu);
|
|
|
|
nTtype = emuQueryEmulatorId(hEmu);
|
|
switch (nTtype)
|
|
{
|
|
case EMU_ANSI:
|
|
strcpy(pszPtr, "ANSI");
|
|
break;
|
|
case EMU_TTY:
|
|
strcpy(pszPtr, "TELETYPE-33");
|
|
break;
|
|
case EMU_VT52:
|
|
strcpy(pszPtr, "DEC-VT52");
|
|
break;
|
|
case EMU_VT100:
|
|
// strcpy(pszPtr, "VT100");
|
|
strcpy(pszPtr, "DEC-VT100");
|
|
break;
|
|
default:
|
|
strcpy(pszPtr, "DEC-VT100"); // "UNKNOWN");
|
|
break;
|
|
}
|
|
DbgOutStr("NVT: Terminal=%s", pszPtr, 0,0,0,0);
|
|
pszPtr = pszPtr + strlen(pszPtr);
|
|
*pszPtr++ = (UCHAR)IAC;
|
|
*pszPtr++ = (UCHAR)SE;
|
|
|
|
WinSockSendBuffer(hhDriver,
|
|
pszPtr - (LPSTR)acTerm,
|
|
(LPSTR)acTerm);
|
|
hhDriver->NVTstate = NVT_THRU;
|
|
return NVT_DISCARD ;
|
|
default:
|
|
break;
|
|
}
|
|
hhDriver->NVTstate = NVT_THRU;
|
|
return NVT_KEEP;
|
|
|
|
default:
|
|
hhDriver->NVTstate = NVT_THRU;
|
|
return NVT_KEEP;
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|