4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This file contains an 'Intel UEFI Application' and is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync licensed for Intel CPUs and chipsets under the terms of your
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync license agreement with Intel or your vendor. This file may
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync be modified by the user, subject to additional terms of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync license agreement
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*++
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (c) 2011 Intel Corporation. All rights reserved
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThis software and associated documentation (if any) is furnished
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncunder a license and may only be used or copied in accordance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwith the terms of the license. Except as permitted by such
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynclicense, no part of this software or documentation may be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncreproduced, stored in a retrieval system, or transmitted in any
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncform or by any means without the express written consent of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIntel Corporation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync--*/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This is a simple TFTP server application
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <TftpServer.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTSDT_TFTP_SERVER mTftpServer; ///< TFTP server's control structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Add a connection context to the list of connection contexts.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pTftpServer The TFTP server control structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Context structure address, NULL if allocation fails
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTSDT_CONNECTION_CONTEXT *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncContextAdd (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_TFTP_SERVER * pTftpServer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync size_t LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TSDT_CONNECTION_CONTEXT * pContext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Use for/break instead of goto
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for ( ; ; ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate a new context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sizeof ( *pContext );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->AllocatePool ( EfiRuntimeServicesData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (VOID **)&pContext );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_POOL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to allocate the context, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem ( pContext, LengthInBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem ( &pContext->RemoteAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pTftpServer->RemoteAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof ( pContext->RemoteAddress ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->BlockSize = TFTP_MAX_BLOCK_SIZE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->pBuffer = &pContext->FileData[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->pEnd = &pContext->pBuffer[sizeof ( pContext->pBuffer )];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->MaxTransferSize = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->MaxTransferSize -= 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Display the new context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_PORT_WORK | DEBUG_INFO,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Context for %d.%d.%d.%d:%d\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)pContext->RemoteAddress.sin_addr.s_addr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)( pContext->RemoteAddress.sin_addr.s_addr >> 8 ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)( pContext->RemoteAddress.sin_addr.s_addr >> 16 ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)( pContext->RemoteAddress.sin_addr.s_addr >> 24 ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync htons ( pContext->RemoteAddress.sin_port )));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Add the context to the context list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->pNext = pTftpServer->pContextList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->pContextList = pContext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // All done
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the connection context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( pContext );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return pContext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Locate a remote connection context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pTftpServer The TFTP server control structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pIpAddress The start of the remote IP address in network order
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] Port The remote port number
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Context structure address, NULL if not found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTSDT_CONNECTION_CONTEXT *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncContextFind (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_TFTP_SERVER * pTftpServer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TSDT_CONNECTION_CONTEXT * pContext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Walk the list of connection contexts
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext = pTftpServer->pContextList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pContext ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Attempt to locate the remote network connection
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( pTftpServer->RemoteAddress.sin_addr.s_addr == pContext->RemoteAddress.sin_addr.s_addr )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( pTftpServer->RemoteAddress.sin_port == pContext->RemoteAddress.sin_port )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The connection was found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TFTP_REQUEST,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: pContext found\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the next context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext = pContext->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the connection context structure address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_HEX ( pContext );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return pContext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Remove a context from the list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pTftpServer The TFTP server control structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pContext The context structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncContextRemove (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_TFTP_SERVER * pTftpServer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_CONNECTION_CONTEXT * pContext
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TSDT_CONNECTION_CONTEXT * pNextContext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TSDT_CONNECTION_CONTEXT * pPreviousContext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Attempt to locate the context in the list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPreviousContext = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNextContext = pTftpServer->pContextList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( NULL != pNextContext ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if the context was found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pNextContext == pContext ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove the context from the list
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pPreviousContext ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->pContextList = pContext->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPreviousContext->pNext = pContext->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the next context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pPreviousContext = pNextContext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNextContext = pNextContext->pNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if the context was found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pContext ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the resources
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->FreePool ( pContext );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the work for the sockets.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pTftpServer The TFTP server control structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPortWork (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_TFTP_SERVER * pTftpServer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TSDT_CONNECTION_CONTEXT * pContext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync socklen_t RemoteAddressLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Handle input events
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 != ( pTftpServer->TftpPort.revents & POLLRDNORM )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Receive the message from the remote system
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemoteAddressLength = sizeof ( pTftpServer->RemoteAddress );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->RxBytes = recvfrom ( pTftpServer->TftpPort.fd,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pTftpServer->RxBuffer[0],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof ( pTftpServer->RxBuffer ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (struct sockaddr *) &pTftpServer->RemoteAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &RemoteAddressLength );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( -1 != pTftpServer->RxBytes ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->RemoteAddress.sin_len = (UINT8) RemoteAddressLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TFTP_PORT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "Received %d bytes from %d.%d.%d.%d:%d\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->RxBytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->RemoteAddress.sin_addr.s_addr & 0xff,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ( pTftpServer->RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ( pTftpServer->RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ( pTftpServer->RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync htons ( pTftpServer->RemoteAddress.sin_port )));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Lookup connection context using the remote system address and port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // to determine if an existing connection to this remote
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // system exists
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext = ContextFind ( pTftpServer );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Process the received message
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TftpProcessRequest ( pTftpServer, pContext );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Receive error on the TFTP server port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Close the server socket
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed receive on TFTP server port, errno: 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->TftpPort.revents |= POLLHUP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Handle the close event
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 != ( pTftpServer->TftpPort.revents & POLLHUP )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Close the port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync close ( pTftpServer->TftpPort.fd );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->TftpPort.fd = -1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Scan the list of sockets and process any pending work
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pTftpServer The TFTP server control structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSocketPoll (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_TFTP_SERVER * pTftpServer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int FDCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_SOCKET_POLL, "Entering SocketPoll\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if any ports are active
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FDCount = poll ( &pTftpServer->TftpPort,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 1,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CLIENT_POLL_DELAY );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( -1 == FDCount ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_SOCKET_POLL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - errno: %d\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 < FDCount ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Process this port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PortWork ( pTftpServer );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->TftpPort.revents = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_SOCKET_POLL, "Exiting SocketPoll\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Convert a character to lower case
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] Character The character to convert
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The lower case equivalent of the character
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncint
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynctolower (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int Character
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if the character is upper case
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( 'A' <= Character ) && ( 'Z' >= Character )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Convert the character to lower caes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Character += 'a' - 'A';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the converted character
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Character;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Case independent string comparison
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pString1 Zero terminated string address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pString2 Zero terminated string address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Returns the first character difference between string 1
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and string 2.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncint
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstricmp (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync char * pString1,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync char * pString2
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int Char1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int Char2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int Difference;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Walk the length of the strings
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the next characters
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Char1 = (UINT8)*pString1++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Char2 = (UINT8)*pString2++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Convert them to lower case
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Char1 = tolower ( Char1 );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Char2 = tolower ( Char2 );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Done when the characters differ
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Difference = Char1 - Char2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 != Difference ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Done at the end of the string
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while ( 0 != Char1 );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the difference
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Difference;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get the next TFTP option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pOption Address of a zero terminated option string
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pEnd End of buffer address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] ppNextOption Address to receive the address of the next
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync zero terminated option string
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Message processed successfully
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTftpOptionGet (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 * pOption,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 * pEnd,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 ** ppNextOption
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pNextOption;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate the end of the option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNextOption = pOption;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (( pEnd > pNextOption ) && ( 0 != *pNextOption )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNextOption += 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pEnd <= pNextOption ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Error - end of buffer reached
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_TFTP_REQUEST,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Option without zero termination received!\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Zero terminated option found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pNextOption += 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Display the zero terminated ASCII option string
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TFTP_REQUEST,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "Option: %a\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOption ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the next option address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppNextOption = pNextOption;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Place an option value into the option acknowledgement
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pOack Option acknowledgement address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] Value Value to translate into ASCII decimal
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Option acknowledgement address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT8 *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTftpOptionSet (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 * pOack,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT64 Value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 NextValue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine the next value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NextValue = Value / 10;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Supress leading zeros
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 != NextValue ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOack = TftpOptionSet ( pOack, NextValue );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Output this digit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = (UINT8)( Value - ( NextValue * 10 ) + '0' );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the next option acknowledgement location
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return pOack;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the TFTP request
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pContext The context structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pOption Address of the first zero terminated option string
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pEnd End of buffer address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTftpOptions (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_CONNECTION_CONTEXT * pContext,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 * pOption,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 * pEnd
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pNextOption;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pOack;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pTemp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pValue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync INT32 Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Start the OACK packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Let the OACK handle the parsing errors
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // See http://tools.ietf.org/html/rfc2347
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOack = &pContext->TxBuffer[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = TFTP_OP_OACK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->TxBytes = 2;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Walk the list of options
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the next option, skip junk at end of message
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TftpOptionGet ( pOption, pEnd, &pNextOption );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Process the option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // blksize - See http://tools.ietf.org/html/rfc2348
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pValue = pNextOption;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 == stricmp ((char *)pOption, "blksize" )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TftpOptionGet ( pValue, pEnd, &pNextOption );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the block size, skip non-numeric block sizes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TftpOptionValue ( pValue, &Value );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Propose a smaller block size if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( Value > TFTP_MAX_BLOCK_SIZE ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = TFTP_MAX_BLOCK_SIZE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the new block size
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->BlockSize = Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TFTP_REQUEST,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "Using block size of %d bytes\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->BlockSize ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the OACK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTemp = pOack;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 'b';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 'l';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 'k';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 's';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 'i';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 'z';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 'e';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOack = TftpOptionSet ( pOack, pContext->BlockSize );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->TxBytes += pOack - pTemp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // timeout - See http://tools.ietf.org/html/rfc2349
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if ( 0 == stricmp ((char *)pOption, "timeout" )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TftpOptionGet ( pValue, pEnd, &pNextOption );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TftpOptionValue ( pValue, &Value );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the timeout value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->Timeout = Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TFTP_REQUEST,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "Using timeout of %d seconds\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->Timeout ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the OACK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTemp = pOack;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 't';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 'i';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 'm';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 'e';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 'o';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 'u';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 't';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOack = TftpOptionSet ( pOack, pContext->Timeout );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->TxBytes += pOack - pTemp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // tsize - See http://tools.ietf.org/html/rfc2349
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if ( 0 == stricmp ((char *)pOption, "tsize" )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TftpOptionGet ( pValue, pEnd, &pNextOption );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TftpOptionValue ( pValue, &Value );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the file size
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TFTP_REQUEST,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "Returning file size of %Ld bytes\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->LengthInBytes ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the OACK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTemp = pOack;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 't';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 's';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 'i';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 'z';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 'e';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOack = TftpOptionSet ( pOack, pContext->LengthInBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pOack++ = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->TxBytes += pOack - pTemp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Unknown option - Ignore it
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_WARN | DEBUG_TFTP_REQUEST,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "WARNING - Skipping unknown option: %a\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOption ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the next option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOption = pNextOption;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while ( pEnd > pOption );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the TFTP request
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pOption Address of the first zero terminated option string
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pValue Address to receive the value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Option translated into a value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTftpOptionValue (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 * pOption,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN INT32 * pValue
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Digit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync INT32 Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Walk the characters in the option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( 0 != *pOption ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Convert the next digit to binary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Digit = *pOption++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( '0' <= Digit ) && ( '9' >= Digit )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value *= 10;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value += Digit - '0';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_TFTP_REQUEST,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Invalid character '0x%02x' in the value\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Digit ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pValue = Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the conversion status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the TFTP request
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pTftpServer The TFTP server control structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pContext Connection context structure address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTftpProcessRequest (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_TFTP_SERVER * pTftpServer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_CONNECTION_CONTEXT * pContext
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN bCloseContext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN bIgnorePacket;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 BlockNumber;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Opcode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pEnd;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pFileName;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pMode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pOption;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the opcode
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = &pTftpServer->RxBuffer[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Opcode = HTONS ( *(UINT16 *)&pBuffer[0]);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPrint ( L"TFTP Opcode: 0x%08x\r\n", Opcode );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the parameters
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bCloseContext = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bIgnorePacket = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch ( Opcode ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TFTP_REQUEST,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Unknown TFTP opcode: %d\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Opcode ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bIgnorePacket = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case TFTP_OP_READ_REQUEST:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case TFTP_OP_DATA:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pContext ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - File not open for %d.%d.%d.%d:%d\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)pTftpServer->RemoteAddress.sin_addr.s_addr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 8 ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 16 ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 24 ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync htons ( pTftpServer->RemoteAddress.sin_port )));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bIgnorePacket = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pContext->bExpectAck ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Expecting ACKs not data for pContext 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bIgnorePacket = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pTftpServer->RxBytes > (ssize_t)( pContext->BlockSize + 2 + 2 )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Receive data length of %d > %d bytes (maximum block size) for pContext 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->RxBytes - 2 - 2,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->BlockSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bIgnorePacket = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case TFTP_OP_ACK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pContext ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - File not open for %d.%d.%d.%d:%d\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)pTftpServer->RemoteAddress.sin_addr.s_addr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 8 ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 16 ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 24 ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync htons ( pTftpServer->RemoteAddress.sin_port )));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bIgnorePacket = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !pContext->bExpectAck ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Expecting data not ACKs for pContext 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bIgnorePacket = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case TFTP_OP_ERROR:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pContext ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - File not open for %d.%d.%d.%d:%d\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)pTftpServer->RemoteAddress.sin_addr.s_addr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 8 ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 16 ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 24 ),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync htons ( pTftpServer->RemoteAddress.sin_port )));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bIgnorePacket = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !bIgnorePacket ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Process the request
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch ( Opcode ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TFTP_REQUEST,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Unable to process TFTP opcode: %d\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Opcode ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case TFTP_OP_READ_REQUEST:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Close the context if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL != pContext ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ContextRemove ( pTftpServer, pContext );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create the connection context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext = ContextAdd ( pTftpServer );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( NULL == pContext ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate the mode
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pFileName = &pBuffer[2];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pEnd = &pBuffer[pTftpServer->RxBytes];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pMode = pFileName;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (( pEnd > pMode ) && ( 0 != *pMode )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pMode += 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pEnd <= pMode ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Mode not found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_RX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - File mode not found\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Tell the client of the error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TftpSendError ( pTftpServer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8 *)"File open mode not found" );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pMode += 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TFTP_REQUEST,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TFTP - FileName: %a\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pFileName ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Locate the options
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOption = pMode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (( pEnd > pOption ) && ( 0 != *pOption )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOption += 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pEnd <= pOption ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // End of mode not found
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_RX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - File mode not valid\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Tell the client of the error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TftpSendError ( pTftpServer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8 *)"File open mode not valid" );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pOption += 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TFTP_REQUEST,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TFTP - Mode: %a\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pMode ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Verify the mode is supported
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 != stricmp ((char *)pMode, "octet" )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // File access mode not supported
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_TFTP_REQUEST,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - File mode %a not supported\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pMode ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Tell the client of the error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TftpSendError ( pTftpServer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8 *)"File open mode not supported" );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Open the file, close the context on error
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// TODO: Remove the following line
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncpContext->File = (EFI_HANDLE)1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine the file length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//fstat
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Process the options
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TftpOptions ( pContext, pOption, pEnd );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Read in the first portion of the file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send the first block
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->bExpectAck = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 2 < pContext->TxBytes ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send the OACK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TftpTxPacket ( pTftpServer, pContext );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send the first block of data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TftpSendNextBlock ( pTftpServer, pContext );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case TFTP_OP_ACK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the block number that is being ACKed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockNumber = pTftpServer->RxBuffer[2];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockNumber <<= 8;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockNumber |= pTftpServer->RxBuffer[3];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if this is the correct ACK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TFTP_ACK,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ACK for block 0x%04x received\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockNumber ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( !pContext->bExpectAck )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || ( BlockNumber != pContext->AckNext )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_WARN | DEBUG_TFTP_ACK,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "WARNING - Expecting ACK 0x%0x4 not received ACK 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->AckNext,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BlockNumber ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Process the expected ACK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pContext->bEofSent ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bCloseContext = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the next expected ACK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->AckNext += 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send the next packet of data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TftpSendNextBlock ( pTftpServer, pContext );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine if the context should be closed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( bCloseContext ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ContextRemove ( pTftpServer, pContext );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Build and send an error packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pTftpServer The TFTP server control structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pContext The context structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] Error Error number for the packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pError Zero terminated error string address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Message processed successfully
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTftpSendError (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_TFTP_SERVER * pTftpServer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_CONNECTION_CONTEXT * pContext,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 Error,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 * pError
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Character;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Build the error packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = &pContext->TxBuffer[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer[0] = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer[1] = TFTP_OP_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer[2] = (UINT8)( Error >> 8 );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer[3] = (UINT8)Error;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Copy the zero terminated string into the buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer += 4;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Character = *pError++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pBuffer++ = Character;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while ( 0 != Character );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send the error message
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->TxBytes = pBuffer - &pContext->TxBuffer[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TftpTxPacket ( pTftpServer, pContext );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Send the next block of file system data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pTftpServer The TFTP server control structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pContext The context structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Message processed successfully
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTftpSendNextBlock (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_TFTP_SERVER * pTftpServer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_CONNECTION_CONTEXT * pContext
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ssize_t LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 * pBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine how much data needs to be sent
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = pContext->BlockSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (( pContext->LengthInBytes < TFTP_MAX_BLOCK_SIZE )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || ( LengthInBytes > (ssize_t)pContext->LengthInBytes )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = (ssize_t)pContext->LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->bEofSent = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the TFTP opcode and block number
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pBuffer = &pContext->TxBuffer[0];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pBuffer++ = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pBuffer++ = TFTP_OP_DATA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pBuffer++ = (UINT8)( pContext->AckNext >> 8 );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pBuffer++ = (UINT8)pContext->AckNext;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Copy the file data into the transmit buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->TxBytes = 2 + 2 + LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( 0 < LengthInBytes ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem ( &pBuffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->pBuffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send the next block
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TftpTxPacket ( pTftpServer, pContext );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create the port for the TFTP server
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This routine polls the network layer to create the TFTP port for the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TFTP server. More than one attempt may be necessary since it may take
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync some time to get the IP address and initialize the upper layers of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the network stack.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pTftpServer The TFTP server control structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTftpServerTimer (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_TFTP_SERVER * pTftpServer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 TftpPort;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int SocketStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_SERVER_TIMER, "Entering TftpServerTimer\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Open the TFTP port on the server
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Wait for a while
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CheckEvent ( pTftpServer->TimerEvent );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while ( EFI_SUCCESS != Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Attempt to create the socket for the TFTP server
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->TftpPort.events = POLLRDNORM | POLLHUP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->TftpPort.revents = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->TftpPort.fd = socket ( AF_INET,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SOCK_DGRAM,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IPPROTO_UDP );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( -1 != pTftpServer->TftpPort.fd ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the socket address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem ( &pTftpServer->TftpServerAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof ( pTftpServer->TftpServerAddress ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TftpPort = 69;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TFTP_PORT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TFTP Port: %d\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TftpPort ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->TftpServerAddress.sin_len = sizeof ( pTftpServer->TftpServerAddress );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->TftpServerAddress.sin_family = AF_INET;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->TftpServerAddress.sin_addr.s_addr = INADDR_ANY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->TftpServerAddress.sin_port = htons ( TftpPort );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Bind the socket to the TFTP port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SocketStatus = bind ( pTftpServer->TftpPort.fd,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (struct sockaddr *) &pTftpServer->TftpServerAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->TftpServerAddress.sin_len );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( -1 != SocketStatus ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TFTP_PORT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: Socket bound to port %d\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->TftpPort.fd,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TftpPort ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Release the socket if necessary
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( -1 == SocketStatus ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync close ( pTftpServer->TftpPort.fd );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->TftpPort.fd = -1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Wait until the socket is open
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }while ( -1 == pTftpServer->TftpPort.fd );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_SERVER_TIMER, "Exiting TftpServerTimer\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Start the TFTP server port creation timer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pTftpServer The TFTP server control structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The timer was successfully started.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ALREADY_STARTED The timer is already running.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Other The timer failed to start.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTftpServerTimerStart (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_TFTP_SERVER * pTftpServer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 TriggerTime;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume the timer is already running
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_ALREADY_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !pTftpServer->bTimerRunning ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Compute the poll interval
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TriggerTime = TFTP_PORT_POLL_DELAY * ( 1000 * 10 );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->SetTimer ( pTftpServer->TimerEvent,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimerPeriodic,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TriggerTime );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TFTP_PORT, "TFTP port timer started\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Mark the timer running
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->bTimerRunning = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_TFTP_PORT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to start TFTP port timer, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Stop the TFTP server port creation timer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pTftpServer The TFTP server control structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The TFTP port timer is stopped
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Other Failed to stop the TFTP port timer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTftpServerTimerStop (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_TFTP_SERVER * pTftpServer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume the timer is stopped
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( pTftpServer->bTimerRunning ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Stop the port creation polling
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->SetTimer ( pTftpServer->TimerEvent,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimerCancel,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0 );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TFTP_PORT, "TFT[ port timer stopped\r\n" ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Mark the timer stopped
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer->bTimerRunning = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_TFTP_PORT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Failed to stop TFT[ port timer, Status: %r\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Send the next TFTP packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pTftpServer The TFTP server control structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] pContext The context structure address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Message processed successfully
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTftpTxPacket (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_TFTP_SERVER * pTftpServer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN TSDT_CONNECTION_CONTEXT * pContext
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ssize_t LengthInBytes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_ENTER ( );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Assume success
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send the TFTP packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_TX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "0x%08x: pContext sending 0x%08x bytes\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->TxBytes ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LengthInBytes = sendto ( pTftpServer->TftpPort.fd,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pContext->TxBuffer[0],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->TxBytes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (struct sockaddr *)&pContext->RemoteAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pContext->RemoteAddress.sin_len );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( -1 == LengthInBytes ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG (( DEBUG_ERROR | DEBUG_TX,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ERROR - Transmit failure, errno: 0x%08x\r\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errno ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the operation status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Entry point for the TFTP server application.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] Argc The number of arguments
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param [in] Argv The argument value array
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval 0 The application exited normally.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Other An error occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncint
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncmain (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN int Argc,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN char **Argv
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TSDT_TFTP_SERVER * pTftpServer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create a timer event to start TFTP port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pTftpServer = &mTftpServer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CreateEvent ( EVT_TIMER,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TPL_TFTP_SERVER,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pTftpServer->TimerEvent );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TftpServerTimerStart ( pTftpServer );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !EFI_ERROR ( Status )) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Run the TFTP server forever
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for ( ; ; ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Poll the network layer to create the TFTP port
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // for the tftp server. More than one attempt may
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // be necessary since it may take some time to get
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the IP address and initialize the upper layers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // of the network stack.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TftpServerTimer ( pTftpServer );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Poll the socket for activity
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SocketPoll ( pTftpServer );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while ( -1 != pTftpServer->TftpPort.fd );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// TODO: Remove the following test code
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// Exit when the network connection is broken
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncbreak;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Done with the timer event
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TftpServerTimerStop ( pTftpServer );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CloseEvent ( pTftpServer->TimerEvent );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the final status
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DBG_EXIT_STATUS ( Status );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}