/********************************************************************/ /** Copyright(c) 1998 Microsoft Corporation. **/ /********************************************************************/ //*** // // Filename: exports.c // // Description: Contains routines that are exported to the PPP engine. The // engine calls into these routines for ATCP connections // // History: Feb 26, 1998 Shirish Koti Created original version. // //*** #include #include #include #include #include #include #include #include #include #include #include #include #include #define INCL_HOSTWIRE #include #include #include #include "rasatcp.h" //*** // // Function: AtcpGetInfo // PPP engine calls this routine to get entry points into ATCP // // Parameters: dwProtocolId - unused here! // pInfo - info that we fill out and pass back to PPP engine // // Return: NO_ERROR // //***$ DWORD AtcpGetInfo( IN DWORD dwProtocolId, OUT PPPCP_INFO *pInfo ) { ZeroMemory( pInfo, sizeof(PPPCP_INFO) ); pInfo->Protocol = (DWORD )PPP_ATCP_PROTOCOL; lstrcpy(pInfo->SzProtocolName, "Atcp"); pInfo->Recognize = 7; pInfo->RasCpInit = AtcpInit; pInfo->RasCpBegin = AtcpBegin; pInfo->RasCpReset = AtcpReset; pInfo->RasCpEnd = AtcpEnd; pInfo->RasCpThisLayerUp = AtcpThisLayerUp; pInfo->RasCpMakeConfigRequest = AtcpMakeConfigRequest; pInfo->RasCpMakeConfigResult = AtcpMakeConfigResult; pInfo->RasCpConfigAckReceived = AtcpConfigAckReceived; pInfo->RasCpConfigNakReceived = AtcpConfigNakReceived; pInfo->RasCpConfigRejReceived = AtcpConfigRejReceived; pInfo->RasCpGetNegotiatedInfo = AtcpGetNegotiatedInfo; pInfo->RasCpProjectionNotification = AtcpProjectionNotification; return 0; } //*** // // Function: AtcpInit // PPP engine calls this routine to initialize ATCP // // Parameters: fInitialize - TRUE to initialize, FALSE to de-initialize // // Return: NO_ERROR if things go fine // Errorcode if something fails // //***$ DWORD AtcpInit( IN BOOL fInitialize ) { DWORD dwRetCode=NO_ERROR; if (fInitialize) { // open handle to appletalk stack if (!AtcpHandle) { atcpOpenHandle(); } dwRetCode = atcpStartup(); } else { // if we had a handle open to appletalk stack, close it if (AtcpHandle) { atcpCloseHandle(); } dwRetCode = atcpShutdown(); } return(dwRetCode); } //*** // // Function: AtcpBegin // PPP engine calls this routine to mark starting of a connection // setup. // // Parameters: ppContext - context that we pass back // pInfo - PPPCP_INIT info // // Return: result of the operation // //***$ DWORD AtcpBegin( OUT PVOID *ppContext, IN PVOID pInfo ) { DWORD dwRetCode; PATCPCONN pAtcpConn=NULL; *ppContext = NULL; // open handle to stack if not already done so if (!AtcpHandle) { atcpOpenHandle(); } if (AtcpHandle == NULL) { ATCP_DBGPRINT(("atcpAtkSetup: AtcpHandle is NULL!\n")); return(ARAPERR_IOCTL_FAILURE); } // // allocate, initialize our connection context // if ((pAtcpConn = atcpAllocConnection((PPPCP_INIT *)pInfo)) == NULL) { ATCP_DBGPRINT(("AtcpBegin: malloc failed\n")); return(ERROR_NOT_ENOUGH_MEMORY); } // // tell stack to allocate a context for this connection. Also, reserve a // network addr for this client and get zone, router info // dwRetCode = atcpAtkSetup(pAtcpConn, IOCTL_ATCP_SETUP_CONNECTION); if (dwRetCode != NO_ERROR) { ATCP_DBGPRINT(("AtcpBegin: atcpAtkSetup failed %lx\n",dwRetCode)); LocalFree(pAtcpConn); return(dwRetCode); } ATCP_DBGPRINT(("AtcpBegin: client's network addr %x.%x (%lx)\n", pAtcpConn->ClientAddr.ata_Network,pAtcpConn->ClientAddr.ata_Node,pAtcpConn)); // // allocate Route so we can call RasActivateRoute later... // dwRetCode = RasAllocateRoute( pAtcpConn->hPort, APPLETALK, TRUE, &pAtcpConn->RouteInfo); if (dwRetCode != NO_ERROR) { ATCP_DBGPRINT(("AtcpBegin: RasAllocateRoute failed %lx\n",dwRetCode)); // tell the stack to close the connection atcpCloseAtalkConnection(pAtcpConn); LocalFree(pAtcpConn); return(dwRetCode); } *ppContext = (PVOID)pAtcpConn; return 0; } //*** // // Function: AtcpThisLayerUp // PPP engine calls this routine to tell us ATCP setup is done // // Parameters: pContext - our context // // Return: result of the operation // //***$ DWORD AtcpThisLayerUp( IN PVOID pContext ) { PATCPCONN pAtcpConn; BYTE ConfigInfo[ARAP_BIND_SIZE]; PROTOCOL_CONFIG_INFO *pCfgInfo; PARAP_BIND_INFO pBindInfo; DWORD dwRetCode; pAtcpConn = (PATCPCONN)pContext; ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE); EnterCriticalSection(&pAtcpConn->CritSect); if (pAtcpConn->fLineUpDone) { ATCP_DBGPRINT(("AtcpThisLayerUp: LineUp already done\n")); LeaveCriticalSection(&pAtcpConn->CritSect); return(NO_ERROR); } pAtcpConn->fLineUpDone = TRUE; LeaveCriticalSection(&pAtcpConn->CritSect); if (pAtcpConn->SuppressRtmp || pAtcpConn->SuppressAllBcast) { atcpAtkSetup(pAtcpConn, IOCTL_ATCP_SUPPRESS_BCAST); } pCfgInfo = (PROTOCOL_CONFIG_INFO *)ConfigInfo; pBindInfo = (PARAP_BIND_INFO)&pCfgInfo->P_Info[0]; pCfgInfo->P_Length = ARAP_BIND_SIZE; // // plumb our protocol-specific info // pBindInfo->BufLen = sizeof( ARAP_BIND_INFO ); pBindInfo->pDllContext = pAtcpConn; pBindInfo->fThisIsPPP = TRUE; pBindInfo->ClientAddr = pAtcpConn->ClientAddr; pBindInfo->AtalkContext = pAtcpConn->AtalkContext; pBindInfo->ErrorCode = (DWORD)-1; // // pass it down to ndiswan so our stack gets a line-up! // dwRetCode = RasActivateRoute( pAtcpConn->hPort, APPLETALK, &pAtcpConn->RouteInfo, pCfgInfo); if (dwRetCode != NO_ERROR) { ATCP_DBGPRINT(("AtcpProjectionNotification: RasActivateRoute failed %lx\n", dwRetCode)); return(dwRetCode); } ATCP_DBGPRINT(("AtcpThisLayerUp: LineUp done on %lx\n",pAtcpConn)); return 0; } //*** // // Function: AtcpMakeConfigRequest // PPP engine calls this routine to ask us to prepare an // ATCP ConfigRequest packet // // Parameters: pContext - our context // pSendBuf - PPP_CONFIG info for this request // cbSendBuf - how big is the Data buffer // // Return: result of the operation // //***$ DWORD AtcpMakeConfigRequest( IN PVOID pContext, OUT PPP_CONFIG *pSendBuf, IN DWORD cbSendBuf ) { PATCPCONN pAtcpConn; DWORD dwRetCode; USHORT OptionType; BOOL fConfigDone=FALSE; BYTE ParseResult[ATCP_OPT_MAX_VAL]; pAtcpConn = (PATCPCONN)pContext; ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE); EnterCriticalSection(&pAtcpConn->CritSect); if (pAtcpConn->Flags & ATCP_CONFIG_REQ_DONE) { fConfigDone = TRUE; } LeaveCriticalSection(&pAtcpConn->CritSect); if (fConfigDone) { pSendBuf->Code = CONFIG_REQ; HostToWireFormat16(4, pSendBuf->Length ); ATCP_DBGPRINT(("AtcpMakeConfigRequest: our-side config done, returning\n")); return(NO_ERROR); } // initialize everything to not-needed for (OptionType=1; OptionTypeSignature == ATCP_SIGNATURE); // // parse this request. // dwRetCode = atcpParseRequest( pAtcpConn, pReceiveBuf, pSendBuf, cbSendBuf, ParseResult, &fRejectingSomething); if (dwRetCode != NO_ERROR) { ATCP_DBGPRINT(("AtcpMakeConfigResult: atcpParseRequest failed %lx\n", dwRetCode)); return(dwRetCode); } // // If some option needs to be rejected, the outgoing buffer already // contains the appropriate stuff: just return here // if (fRejectingSomething) { return(NO_ERROR); } // // we are not rejecting any option. Prepare a response buffer to send // dwRetCode = atcpPrepareResponse( pAtcpConn, pSendBuf, cbSendBuf, ParseResult); if (dwRetCode != NO_ERROR) { ATCP_DBGPRINT(("AtcpMakeConfigResult: atcpPrepareResponse failed %lx\n", dwRetCode)); return(dwRetCode); } return(NO_ERROR); } //*** // // Function: AtcpConfigAckReceived // PPP engine calls this routine to tell us that we got ConfigAck // // Parameters: pContext - our context // pReceiveBuf - PPP_CONFIG info: the ack // // Return: result of the operation // //***$ DWORD AtcpConfigAckReceived( IN PVOID pContext, IN PPP_CONFIG *pReceiveBuf ) { PATCPCONN pAtcpConn; pAtcpConn = (PATCPCONN)pContext; ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE); // client is happy with our-side configuration EnterCriticalSection(&pAtcpConn->CritSect); pAtcpConn->Flags |= ATCP_CONFIG_REQ_DONE; LeaveCriticalSection(&pAtcpConn->CritSect); return 0; } //*** // // Function: AtcpConfigNakReceived // PPP engine calls this routine to tell us that we got ConfigNak // // Parameters: pContext - our context // pReceiveBuf - PPP_CONFIG info: the ack // // Return: result of the operation // //***$ DWORD AtcpConfigNakReceived( IN PVOID pContext, IN PPP_CONFIG *pReceiveBuf ) { PATCPCONN pAtcpConn; ATCP_DBGPRINT(("AtcpConfigNakReceived entered\n")); pAtcpConn = (PATCPCONN)pContext; ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE); ATCP_DUMP_BYTES("AtcpConfigNakReceived: Nak received from client", &pReceiveBuf->Data[0], (DWORD)WireToHostFormat16( pReceiveBuf->Length ) - 4); return 0; } //*** // // Function: AtcpConfigRejReceived // PPP engine calls this routine to tell us that we got ConfigRej // // Parameters: pContext - our context // pReceiveBuf - PPP_CONFIG info: the ack // // Return: result of the operation // //***$ DWORD AtcpConfigRejReceived( IN PVOID pContext, IN PPP_CONFIG *pReceiveBuf ) { PATCPCONN pAtcpConn; ATCP_DBGPRINT(("AtcpConfigRejReceived entered\n")); pAtcpConn = (PATCPCONN)pContext; ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE); return 0; } //*** // // Function: AtcpGetNegotiatedInfo // PPP engine calls this routine to retrieve from us the info that // finally got negotiated. // // Parameters: pContext - our context // pReceiveBuf - PPP_CONFIG info: the ack // // Return: result of the operation // //***$ DWORD AtcpGetNegotiatedInfo( IN PVOID pContext, OUT PPP_ATCP_RESULT *pAtcpResult ) { PATCPCONN pAtcpConn; pAtcpConn = (PATCPCONN)pContext; ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE); pAtcpResult->dwError = 0; pAtcpResult->dwLocalAddress = *(DWORD *)&AtcpServerAddress; pAtcpResult->dwRemoteAddress = *(DWORD *)&pAtcpConn->ClientAddr; return 0; } //*** // // Function: AtcpProjectionNotification // PPP engine calls this routine to tell us that all CPs have been // negotiated. // // Parameters: pContext - our context // pProjectionResult - PPP_PROJECTION_RESULT info // // Return: result of the operation // //***$ DWORD AtcpProjectionNotification( IN PVOID pContext, IN PVOID pProjectionResult ) { PATCPCONN pAtcpConn; ATCP_DBGPRINT(("AtcpProjectionNotification entered\n")); pAtcpConn = (PATCPCONN)pContext; ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE); return 0; } //*** // // Function: AtcpReset // Don't know when/why PPP engine calls this routine: this routine // just returns success! // // Parameters: pContext - our context // // Return: always 0 // //***$ DWORD AtcpReset( IN PVOID pContext ) { PATCPCONN pAtcpConn; ATCP_DBGPRINT(("AtcpReset entered\n")); pAtcpConn = (PATCPCONN)pContext; ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE); return 0; } //*** // // Function: AtcpEnd // PPP engine calls this routine to mark end of a connection. // // Parameters: pContext - our context // // Return: result of the operation // //***$ DWORD AtcpEnd( IN PVOID pContext ) { PATCPCONN pAtcpConn; ATCP_DBGPRINT(("AtcpEnd entered\n")); pAtcpConn = (PATCPCONN)pContext; ATCP_ASSERT(pAtcpConn->Signature == ATCP_SIGNATURE); // tell the stack to close the connection atcpCloseAtalkConnection(pAtcpConn); // deactivate the ras route so stack gets a line-down RasDeAllocateRoute(pAtcpConn->hConnection, APPLETALK); if (pAtcpConn->fCritSectInitialized) { DeleteCriticalSection( &pAtcpConn->CritSect ); pAtcpConn->fCritSectInitialized = FALSE; } #if DBG // mess up the memory so we can catch bad things (using free'd memory etc.) memset( pAtcpConn, 'f', sizeof(ATCPCONN) ); pAtcpConn->Signature = 0xDEADBEEF; #endif LocalFree(pAtcpConn); EnterCriticalSection( &AtcpCritSect ); AtcpNumConnections--; LeaveCriticalSection( &AtcpCritSect ); return 0; }