|
|
/********************************************************************/ /** Copyright(c) 1998 Microsoft Corporation. **/ /********************************************************************/
//***
//
// Filename: rasatcp.c
//
// Description: Contains routines that implement the ATCP functionality.
//
// History: Feb 26, 1998 Shirish Koti Created original version.
//
//***
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <lmcons.h>
#include <string.h>
#include <stdlib.h>
#include <llinfo.h>
#include <rasman.h>
#include <rtutils.h>
#include <devioctl.h>
#include <rasppp.h>
#include <pppcp.h>
#define INCL_HOSTWIRE
#include <ppputil.h>
#include <raserror.h>
#include <arapio.h>
#include "rasatcp.h"
//
// Globals
//
HANDLE AtcpHandle=NULL; CRITICAL_SECTION AtcpCritSect; NET_ADDR AtcpServerAddress; NET_ADDR AtcpDefaultRouter; DWORD AtcpNumConnections=0; UCHAR AtcpServerName[NAMESTR_LEN]; UCHAR AtcpZoneName[ZONESTR_LEN];
//***
//
// Function: atcpStartup
// This routine does init time setup
//
// Return: result of operation
//
//***$
DWORD atcpStartup( IN VOID ) { DWORD dwRetCode=NO_ERROR; DWORD dwSrvNameLen=MAX_COMPUTERNAME_LENGTH+1;
// get the server name
if (!GetComputerName((LPTSTR)&AtcpServerName[1],&dwSrvNameLen)) { dwRetCode = GetLastError(); ATCP_DBGPRINT(("atcpStartup: GetComputerName failed %ld\n",dwRetCode)); return(dwRetCode); }
// store it in Pascal string format
AtcpServerName[0] = (BYTE)dwSrvNameLen;
InitializeCriticalSection( &AtcpCritSect );
return(dwRetCode); }
//***
//
// Function: atcpOpenHandle
// Opens the RAS device exported by the appletalk stack
//
// Parameters: None
//
// Return: None
//
// Globals: AtcpHandle, if successful
//
//***$
VOID atcpOpenHandle( IN VOID ) { NTSTATUS status; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING DeviceName; IO_STATUS_BLOCK IoStatus; HANDLE hLocalHandle;
if (AtcpHandle) { ATCP_DBGPRINT(("atcpOpenHandle: handle %lx already open!\n",AtcpHandle)); return; }
RtlInitUnicodeString( &DeviceName, ARAP_DEVICE_NAME );
InitializeObjectAttributes( &ObjectAttributes, &DeviceName, OBJ_CASE_INSENSITIVE, NULL, NULL ); status = NtCreateFile( &hLocalHandle, SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA, &ObjectAttributes, &IoStatus, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF, 0, NULL, 0 );
if ( NT_SUCCESS(status) ) { AtcpHandle = hLocalHandle; ATCP_DBGPRINT(("atcpOpenHandle: NtCreateFile succeeded\n",status)); } else { ATCP_DBGPRINT(("atcpOpenHandle: NtCreateFile failed %lx\n",status)); }
}
//***
//
// Function: atcpCloseHandle
// Closes the RAS device (opened in atcpOpenHandle)
//
// Parameters: None
//
// Return: None
//
// Globals: AtalkHandle
//
//***$
VOID atcpCloseHandle( IN VOID ) { NTSTATUS status=STATUS_SUCCESS;
if (!AtcpHandle) { ATCP_DBGPRINT(("atcpCloseHandle: handle already closed!\n")); return; }
status = NtClose( AtcpHandle );
AtcpHandle = NULL;
if ( !NT_SUCCESS( status ) ) { ATCP_DBGPRINT(("atcpCloseHandle: NtClose failed %lx\n",status)); ATCP_ASSERT(0); } else { ATCP_DBGPRINT(("atcpCloseHandle: NtClose succeeded\n",status)); } }
//***
//
// Function: atcpAtkSetup
// This is the entry point into the stack to tell the stack to
// set up a context for this connection, to get a network address
// for the dial-in client, server's zone name, and router address
//
// Parameters: pAtcpConn - connection context
//
// Return: status returned by NtDeviceIoControlFile
//
//***$
DWORD atcpAtkSetup( IN PATCPCONN pAtcpConn, IN ULONG IoControlCode ) {
NTSTATUS status; IO_STATUS_BLOCK iosb; HANDLE Event; BYTE Buffer[sizeof(ARAP_SEND_RECV_INFO) + sizeof(ATCPINFO)]; PARAP_SEND_RECV_INFO pSndRcvInfo; PATCPINFO pAtcpInfo; PATCP_SUPPRESS_INFO pSupprInfo; DWORD dwRetCode=NO_ERROR;
RtlZeroMemory((PBYTE)Buffer, sizeof(Buffer));
pSndRcvInfo = (PARAP_SEND_RECV_INFO)Buffer; pSndRcvInfo->StatusCode = (DWORD)-1; pSndRcvInfo->pDllContext = (PVOID)pAtcpConn; pSndRcvInfo->IoctlCode = IoControlCode; pSndRcvInfo->ClientAddr = pAtcpConn->ClientAddr;
if (IoControlCode == IOCTL_ATCP_SETUP_CONNECTION) { pSndRcvInfo->DataLen = sizeof(ATCPINFO); } else if (IoControlCode == IOCTL_ATCP_SUPPRESS_BCAST) { // if we don't need to suppress broadcasts, done here
if ((!pAtcpConn->SuppressRtmp) && (!pAtcpConn->SuppressAllBcast)) { return(NO_ERROR); } pSndRcvInfo->DataLen = sizeof(ATCP_SUPPRESS_INFO);
pSupprInfo = (PATCP_SUPPRESS_INFO)&pSndRcvInfo->Data[0]; pSupprInfo->SuppressRtmp = pAtcpConn->SuppressRtmp; pSupprInfo->SuppressAllBcast = pAtcpConn->SuppressAllBcast; } else { pSndRcvInfo->DataLen = 0; }
Event = CreateEvent(NULL, FALSE, FALSE, NULL); if (Event == NULL) { ATCP_DBGPRINT(("atcpAtkSetup: CreateEvent failed (%ld)\n",GetLastError())); return(ARAPERR_OUT_OF_RESOURCES); }
status = NtDeviceIoControlFile( AtcpHandle, Event, // Event
NULL, // ApcRoutine
NULL, // ApcContext
&iosb, // IoStatusBlock
IoControlCode, // IoControlCode
Buffer, // InputBuffer
sizeof(Buffer), // InputBufferSize
Buffer, // OutputBuffer
sizeof(Buffer)); // OutputBufferSize
if (status == STATUS_PENDING) { status = NtWaitForSingleObject( Event, // Handle
TRUE, // Alertable
NULL); // Timeout
if (NT_SUCCESS(status)) { status = iosb.Status; } }
if (status != STATUS_SUCCESS) { ATCP_DBGPRINT(("atcpAtkSetup: NtDeviceIoControlFile failure (%lx)\n", status)); dwRetCode = ARAPERR_IOCTL_FAILURE; }
CloseHandle(Event);
dwRetCode = pSndRcvInfo->StatusCode;
if (dwRetCode != NO_ERROR) { ATCP_DBGPRINT(("atcpAtkSetup: ioctl %lx failed %ld\n", IoControlCode,dwRetCode)); return(dwRetCode); }
//
// for SETUP ioctl, we have some info from stack we need to copy
//
if (IoControlCode == IOCTL_ATCP_SETUP_CONNECTION) { pAtcpInfo = (PATCPINFO)&pSndRcvInfo->Data[0];
// get the client's address out
EnterCriticalSection(&pAtcpConn->CritSect);
pAtcpConn->AtalkContext = pSndRcvInfo->AtalkContext; pAtcpConn->ClientAddr = pSndRcvInfo->ClientAddr;
LeaveCriticalSection(&pAtcpConn->CritSect);
//
// get the default router's address and the zone name
//
EnterCriticalSection( &AtcpCritSect );
AtcpServerAddress = pAtcpInfo->ServerAddr; AtcpDefaultRouter = pAtcpInfo->DefaultRouterAddr;
ATCP_ASSERT(pAtcpInfo->ServerZoneName[0] < ZONESTR_LEN);
CopyMemory(&AtcpZoneName[1], &pAtcpInfo->ServerZoneName[1], pAtcpInfo->ServerZoneName[0]);
AtcpZoneName[0] = pAtcpInfo->ServerZoneName[0];
// got one more connection!
AtcpNumConnections++;
LeaveCriticalSection( &AtcpCritSect ); }
return(dwRetCode); }
//***
//
// Function: atcpAllocConnection
// This routine allocates an ATCP connection block, initializes
// it with info provided by PPP engine.
//
// Parameters: pInfo - PPPCP_INIT info
//
// Return: pointer to ATCP connection if successful, NULL otherwise
//
//***$
PATCPCONN atcpAllocConnection( IN PPPCP_INIT *pPppInit ) { PATCPCONN pAtcpConn=NULL;
pAtcpConn = (PATCPCONN)LocalAlloc(LPTR, sizeof(ATCPCONN));
if (pAtcpConn == NULL) { ATCP_DBGPRINT(("atcpAllocConnection: malloc failed\n")); return(NULL); }
memset( pAtcpConn, 0, sizeof(ATCPCONN) );
pAtcpConn->Signature = ATCP_SIGNATURE;
// by default, broadcasts are not suppressed
pAtcpConn->SuppressRtmp = FALSE; pAtcpConn->SuppressAllBcast = FALSE;
pAtcpConn->fLineUpDone = FALSE;
InitializeCriticalSection( &pAtcpConn->CritSect );
pAtcpConn->hPort = pPppInit->hPort; pAtcpConn->hConnection = pPppInit->hConnection;
return(pAtcpConn); }
//***
//
// Function: atcpParseRequest
// This routine parses the incoming ATCP packet and prepares a
// response as appropriate (Rej, Nak or Ack)
//
// AppleTalk-Address
// 1 6 0 AT-NET(2) AT-Node (1)
// Routing-Protocol
// 2 4 0 0 (Routing protocol - last 2 bytes - can be 0, 1, 2, 3:
// we only support 0)
// Suppress-Broadcasts
// 3 2 (to suppress all broadcasts)
// 3 3 1 (to suppress RTMP bcasts. We don't support other types)
// AT-Compression-Protocol
// 4 4 Undefined!
// Server-information
// 6 Len .....
// Zone-Information
// 7 Len ZoneName
// Default-Router-Address
// 8 6 0 AT-NET(2) AT-Node (1)
//
//
// Parameters: pAtcpConn - the connection
// pReceiveBuf - PPP_CONFIG info: the request
// pSendBuf - PPP_CONFIG info: our response
// cbSendBuf - how big is the Data buffer for our response (for Rej)
// ParseResult - array where we mark off options we saw
// pfRejectingSomething - pointer to TRUE if Rejecting something
//
// Return: result of the operation
//
//***$
DWORD atcpParseRequest( IN PATCPCONN pAtcpConn, IN PPP_CONFIG *pReceiveBuf, OUT PPP_CONFIG *pSendBuf, IN DWORD cbSendBuf, OUT BYTE ParseResult[ATCP_OPT_MAX_VAL+1], OUT BOOL *pfRejectingSomething ) { PPP_OPTION UNALIGNED *pRequest; PPP_OPTION UNALIGNED *pReject; DWORD BytesLeftInSendBuf; PBYTE pOptData; USHORT OptDataLen; USHORT PktLen; USHORT RequestLen; USHORT UnParsedBytes; NET_ADDR ClientAddr; DWORD i;
*pfRejectingSomething = FALSE;
pRequest = (PPP_OPTION UNALIGNED* )pReceiveBuf->Data; pReject = (PPP_OPTION UNALIGNED* )pSendBuf->Data;
BytesLeftInSendBuf = cbSendBuf;
PktLen = WireToHostFormat16( pReceiveBuf->Length ); UnParsedBytes = PktLen - PPP_CONFIG_HDR_LEN;
// initialize for now to "nothing requested"
for (i=0; i<ATCP_OPT_MAX_VAL; i++) { ParseResult[i] = ATCP_NOT_REQUESTED; }
//
// we loop until we have parsed all the bytes
//
while (UnParsedBytes > 0) { RequestLen = (USHORT)pRequest->Length;
if (UnParsedBytes < RequestLen) { ATCP_DBGPRINT(("atcpParseRequest: too few bytes %d vs. %d\n", UnParsedBytes,RequestLen)); return(ERROR_PPP_INVALID_PACKET); }
//
// assume we're going to accept this option. We'll overwrite if that's
// not the case
//
ParseResult[pRequest->Type] = ATCP_ACK;
// the point where the data portion for this option starts
pOptData = &pRequest->Data[0];
// remove the Type and Len bytes, remaining is option data
OptDataLen = RequestLen - 2;
#if 0
ATCP_DBGPRINT(("atcpParseRequest: type %d OptLen %d (", pRequest->Type,OptDataLen)); for (i=0; i<OptDataLen; i++) { DbgPrint(" 0x%x",pOptData[i]); } DbgPrint(" )\n"); #endif
//
// now look at each of the options and see if we should reject it,
// modify it or accept it (Rej, Nak or Ack)
//
switch (pRequest->Type) { //
// client wants an appletalk address. We don't allow the client to
// request which address he wants.
//
case ATCP_OPT_APPLETALK_ADDRESS:
if (RequestLen != 6) { ATCP_DBGPRINT(("atcpParseRequest: AT_ADDR wrong pktlen %d\n", RequestLen)); return(ERROR_PPP_INVALID_PACKET); }
ClientAddr.ata_Network = WireToHostFormat16(&pOptData[1]);
ClientAddr.ata_Node = (USHORT)pOptData[3];
if ((ClientAddr.ata_Network == 0) || (ClientAddr.ata_Node == 0) || (ClientAddr.ata_Network != pAtcpConn->ClientAddr.ata_Network) || (ClientAddr.ata_Node != pAtcpConn->ClientAddr.ata_Node)) { ParseResult[pRequest->Type] = ATCP_NAK; }
break;
//
// client wants some routing protocol. we don't send out Routing
// info, so we should just Nak this option (unless the client also
// is telling us not to send any routing info)
//
case ATCP_OPT_ROUTING_PROTOCOL:
if (RequestLen < 4) { ATCP_DBGPRINT(("atcpParseRequest: ROUTING wrong pktlen %d\n", RequestLen)); return(ERROR_PPP_INVALID_PACKET); }
//
// we don't send out Routing info, so attempt to negotiate any
// other protocol should be Nak'ed
//
if ((*(USHORT *)&pOptData[0]) != ATCP_OPT_ROUTING_NONE) { ParseResult[pRequest->Type] = ATCP_NAK; }
break;
//
// client wants to suppress broadcasts of some (or all) types of
// DDP types.
//
case ATCP_OPT_SUPPRESS_BROADCAST:
//
// client wants us to suppress only some bcasts?
//
if (OptDataLen > 0) { // if requesting RTMP data suppression, we'll allow it
if (pOptData[0] == DDPPROTO_RTMPRESPONSEORDATA) { pAtcpConn->SuppressRtmp = TRUE; }
// hmm, some other protocol: sorry, no can do
else { ATCP_DBGPRINT(("atcpParseRequest: Naking suppression %d\n", pOptData[0])); ParseResult[pRequest->Type] = ATCP_NAK; } } else { pAtcpConn->SuppressAllBcast = TRUE; }
break;
//
// client wants to negotiate some compression. No compression
// scheme is defined, so we just have to reject this option
//
case ATCP_OPT_AT_COMPRESSION_PROTOCOL:
ATCP_DBGPRINT(("atcpParseRequest: COMPRESSION sending Rej\n"));
if (BytesLeftInSendBuf >= RequestLen) { CopyMemory((PVOID)pReject, (PVOID)pRequest, RequestLen); BytesLeftInSendBuf -= RequestLen; } else { ATCP_DBGPRINT(("atcpParseRequest: PPP engine's buffer too small\n", RequestLen)); return(ERROR_BUFFER_TOO_SMALL); }
pReject = (PPP_OPTION UNALIGNED *)((BYTE* )pReject + RequestLen);
*pfRejectingSomething = TRUE;
ParseResult[pRequest->Type] = ATCP_REJ;
break;
//
// for the following options, we just take note of the fact that
// the client has requested it and we send the info over. Nothing
// to negotiate in these options.
// (We aren't supposed to Nak these either)
//
case ATCP_OPT_RESERVED: case ATCP_OPT_SERVER_INFORMATION: case ATCP_OPT_ZONE_INFORMATION: case ATCP_OPT_DEFAULT_ROUTER_ADDRESS:
break;
default:
ATCP_DBGPRINT(("atcpParseRequest: unknown type %d\n", pRequest->Type)); return(ERROR_PPP_INVALID_PACKET); }
//
// move to the next option
//
UnParsedBytes -= RequestLen;
pRequest = (PPP_OPTION UNALIGNED *)((BYTE* )pRequest + RequestLen); }
//
// see if we are rejecting some option. If so, set some values
//
if (*pfRejectingSomething) { pSendBuf->Code = CONFIG_REJ;
HostToWireFormat16( (USHORT)((PBYTE)pReject - (PBYTE)pSendBuf), pSendBuf->Length );
ATCP_DUMP_BYTES("atcpParseRequest: Rejecting these options:", &pSendBuf->Data[0], (DWORD)WireToHostFormat16( pSendBuf->Length)-4); } return(NO_ERROR); }
//***
//
// Function: atcpPrepareResponse
// This routine prepares a response, depending on what all info
// was parsed out from the client's request.
//
// Parameters: pAtcpConn - the connection
// pSendBuf - PPP_CONFIG info: our response
// cbSendBuf - how big is the Data buffer for our response
// ParseResult - array where we have the parsed info
//
// Return: result of the operation
//
//***$
DWORD atcpPrepareResponse( IN PATCPCONN pAtcpConn, OUT PPP_CONFIG *pSendBuf, IN DWORD cbSendBuf, OUT BYTE ParseResult[ATCP_OPT_MAX_VAL+1] ) { DWORD dwRetCode=NO_ERROR; DWORD BytesLeftInSendBuf; PPP_OPTION UNALIGNED *pResponse; PBYTE pOptData; USHORT OptDataLen; USHORT OptionType; DWORD i; BOOL fNakingSomething=FALSE; BOOL fRequestingSomething=FALSE; BOOL fIncludeThisOption;
pResponse = (PPP_OPTION UNALIGNED* )pSendBuf->Data; BytesLeftInSendBuf = cbSendBuf;
// first find out if we are going to be Nak'ing anything
for (OptionType=1; OptionType<ATCP_OPT_MAX_VAL; OptionType++ ) { if (ParseResult[OptionType] == ATCP_NAK) { fNakingSomething = TRUE; } }
//
// go through our array to see which options we must send Nak to
// (or construct Ack for the whole request)
//
for (OptionType=1; OptionType<ATCP_OPT_MAX_VAL; OptionType++ ) { //
// if this option is not (to be) requested, we don't send anything
//
if (ParseResult[OptionType] == ATCP_NOT_REQUESTED) { continue; }
// if Nak'ing something and it's not this option to be Nak'ed, skip it
if (fNakingSomething && (ParseResult[OptionType] != ATCP_NAK)) { continue; }
//
// make sure we have at least 2 bytes for the OptionType and OptionLen
//
if (BytesLeftInSendBuf < 2) { ATCP_DBGPRINT(("atcpPrepareResponse: A: buf too small\n")); return(ERROR_BUFFER_TOO_SMALL); }
BytesLeftInSendBuf -= 2;
pOptData = &pResponse->Data[0]; OptDataLen = 0;
fIncludeThisOption = TRUE;
switch (OptionType) { //
// tell client (again) the client's network address
//
case ATCP_OPT_APPLETALK_ADDRESS:
OptDataLen = sizeof(NET_ADDR);
if (BytesLeftInSendBuf < OptDataLen) { ATCP_DBGPRINT(("atcpPrepareResponse: B: buf too small\n")); return(ERROR_BUFFER_TOO_SMALL); }
// skip the reserved byte
*pOptData++ = 0;
//
// if we are sending our REQUEST, send server's address
//
if (ParseResult[OptionType] == ATCP_REQ) { // put in the network address
HostToWireFormat16(AtcpServerAddress.ata_Network, pOptData); pOptData += sizeof(USHORT);
// put in the network node
ATCP_ASSERT(pAtcpConn->ClientAddr.ata_Node != 0); *pOptData++ = (BYTE)AtcpServerAddress.ata_Node;
fRequestingSomething = TRUE; }
//
// no, we must send the client's network address
//
else { // put in the network address
HostToWireFormat16(pAtcpConn->ClientAddr.ata_Network, pOptData); pOptData += sizeof(USHORT);
// put in the network node
ATCP_ASSERT(pAtcpConn->ClientAddr.ata_Node != 0); *pOptData++ = (BYTE)pAtcpConn->ClientAddr.ata_Node; }
break;
//
// tell client (again) that we support no routing info
//
case ATCP_OPT_ROUTING_PROTOCOL:
OptDataLen = sizeof(USHORT);
HostToWireFormat16(ATCP_OPT_ROUTING_NONE, pOptData); pOptData += sizeof(USHORT); break;
//
// tell client that we can suppress RTMP or all Bcast
//
case ATCP_OPT_SUPPRESS_BROADCAST:
// if this is an ack, see if we have agreed to suppressing RTMP
if (!fNakingSomething) { if (pAtcpConn->SuppressRtmp) { OptDataLen = 1; *pOptData++ = DDPPROTO_RTMPRESPONSEORDATA; } }
break;
//
// we reach here only if are Acking the client's entire request
//
case ATCP_OPT_SERVER_INFORMATION:
ATCP_ASSERT(ParseResult[OptionType] != ATCP_NAK); ATCP_ASSERT(!fNakingSomething);
OptDataLen = sizeof(USHORT) + sizeof(DWORD) + AtcpServerName[0];
if (BytesLeftInSendBuf < OptDataLen) { ATCP_DBGPRINT(("atcpPrepareResponse: C: buf too small\n")); return(ERROR_BUFFER_TOO_SMALL); }
// copy the server's class-id
HostToWireFormat16(ATCP_SERVER_CLASS, pOptData); pOptData += sizeof(USHORT);
// copy the server's implementation-id
HostToWireFormat32(ATCP_SERVER_IMPLEMENTATION_ID, pOptData); pOptData += sizeof(DWORD);
// copy the server's name
CopyMemory(pOptData, &AtcpServerName[1], AtcpServerName[0]);
break;
//
// we reach here only if are Acking the client's entire request
//
case ATCP_OPT_ZONE_INFORMATION:
ATCP_ASSERT(ParseResult[OptionType] != ATCP_NAK); ATCP_ASSERT(!fNakingSomething);
// if we don't have a zone name, skip this option
if (AtcpZoneName[0] == 0) { fIncludeThisOption = FALSE; break; }
OptDataLen = AtcpZoneName[0];
if (BytesLeftInSendBuf < OptDataLen) { ATCP_DBGPRINT(("atcpPrepareResponse: D: buf too small\n")); return(ERROR_BUFFER_TOO_SMALL); }
// copy the zone name
CopyMemory(pOptData, &AtcpZoneName[1], AtcpZoneName[0]);
break;
//
// we reach here only if are Acking the client's entire request
//
case ATCP_OPT_DEFAULT_ROUTER_ADDRESS:
ATCP_ASSERT(ParseResult[OptionType] != ATCP_NAK); ATCP_ASSERT(!fNakingSomething);
// if we don't have a router address, skip this option
if (AtcpDefaultRouter.ata_Network == 0) { fIncludeThisOption = FALSE; break; }
OptDataLen = sizeof(NET_ADDR);
if (BytesLeftInSendBuf < OptDataLen) { ATCP_DBGPRINT(("atcpPrepareResponse: E: buf too small\n")); return(ERROR_BUFFER_TOO_SMALL); }
// skip the reserved byte
*pOptData++ = 0;
// put in the network address
HostToWireFormat16(AtcpDefaultRouter.ata_Network, pOptData); pOptData += sizeof(USHORT);
// put in the network node
*pOptData++ = (BYTE)AtcpDefaultRouter.ata_Node;
break;
default: ATCP_DBGPRINT(("atcpPrepareResponse: opt %d ignored\n",OptionType)); ATCP_ASSERT(0); break; }
if (fIncludeThisOption) { BytesLeftInSendBuf -= OptDataLen;
pResponse->Type = (BYTE)OptionType; pResponse->Length = OptDataLen + 2; // 2 = 1 Type byte + 1 Length byte
pResponse = (PPP_OPTION UNALIGNED *) ((BYTE* )pResponse + pResponse->Length); }
}
HostToWireFormat16( (USHORT)((PBYTE)pResponse - (PBYTE)pSendBuf), pSendBuf->Length );
pSendBuf->Code = (fNakingSomething) ? CONFIG_NAK : ((fRequestingSomething)? CONFIG_REQ : CONFIG_ACK);
#if 0
if (pSendBuf->Code == CONFIG_REQ) { ATCP_DUMP_BYTES("atcpParseRequest: Sending our request:", &pSendBuf->Data[0], (DWORD)WireToHostFormat16( pSendBuf->Length)-4); } else if (pSendBuf->Code == CONFIG_NAK) { ATCP_DUMP_BYTES("atcpParseRequest: Nak'ing these options:", &pSendBuf->Data[0], (DWORD)WireToHostFormat16( pSendBuf->Length)-4); } else { ATCP_DUMP_BYTES("atcpParseRequest: Ack packet from us to client:", &pSendBuf->Data[0], (DWORD)WireToHostFormat16( pSendBuf->Length)-4); } #endif
return(NO_ERROR); }
//***
//
// Function: atcpCloseAtalkConnection
// This routine tells the stack to close this ATCP connection
//
// Parameters: pAtcpConn - the connection to close
//
// Return: result of the operation
//
//***$
DWORD atcpCloseAtalkConnection( IN PATCPCONN pAtcpConn ) { DWORD dwRetCode=NO_ERROR;
// tell the stack that this connection is going away!
dwRetCode = atcpAtkSetup(pAtcpConn, IOCTL_ATCP_CLOSE_CONNECTION);
return(dwRetCode); }
#if DBG
//***
//
// Function: atcpDumpBytes
// DEBUG only: This routine dumps out a given packet to debugger
//
// Parameters: Str - string, if any, to be printed out
// Packet - packet!
// PacketLen - how big is the packet
//
// Return: none
//
//***$
VOID atcpDumpBytes( IN PBYTE Str, IN PBYTE Packet, IN DWORD PacketLen ) {
DWORD i;
if (Str) { DbgPrint("%s: Packet size %ld\n ",Str,PacketLen); } else { DbgPrint("Packet size %ld\n ",PacketLen); }
for (i=0; i<PacketLen; i++) { DbgPrint("%x ",Packet[i]); } DbgPrint("\n"); } #endif
|