Merged socket development branch:
* Add TCPv6 support to DataSink * Add TCPv6 support to DataSource * Add GetAddrInfo test application * Add GetNameInfo test application * Fixed copyright date * Completed TFTP server - now downloads files from local directory * Added ports and exit pages to web server * Made PCD values package specific Signed-off-by: lpleahy git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13003 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
92
AppPkg/Applications/Sockets/WebServer/Exit.c
Normal file
92
AppPkg/Applications/Sockets/WebServer/Exit.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/*++
|
||||
This file contains an 'Intel UEFI Application' and is
|
||||
licensed for Intel CPUs and chipsets under the terms of your
|
||||
license agreement with Intel or your vendor. This file may
|
||||
be modified by the user, subject to additional terms of the
|
||||
license agreement
|
||||
--*/
|
||||
/*++
|
||||
|
||||
Copyright (c) 2011 Intel Corporation. All rights reserved
|
||||
This software and associated documentation (if any) is furnished
|
||||
under a license and may only be used or copied in accordance
|
||||
with the terms of the license. Except as permitted by such
|
||||
license, no part of this software or documentation may be
|
||||
reproduced, stored in a retrieval system, or transmitted in any
|
||||
form or by any means without the express written consent of
|
||||
Intel Corporation.
|
||||
|
||||
--*/
|
||||
|
||||
/** @file
|
||||
Exit response page
|
||||
|
||||
**/
|
||||
|
||||
#include <WebServer.h>
|
||||
|
||||
|
||||
/**
|
||||
Respond with the Exit page
|
||||
|
||||
@param [in] SocketFD The socket's file descriptor to add to the list.
|
||||
@param [in] pPort The WSDT_PORT structure address
|
||||
@param [out] pbDone Address to receive the request completion status
|
||||
|
||||
@retval EFI_SUCCESS The request was successfully processed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ExitPage (
|
||||
IN int SocketFD,
|
||||
IN WSDT_PORT * pPort,
|
||||
OUT BOOLEAN * pbDone
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
DBG_ENTER ( );
|
||||
|
||||
//
|
||||
// Send the Hello World page
|
||||
//
|
||||
for ( ; ; ) {
|
||||
//
|
||||
// Tell the web-server to exit
|
||||
//
|
||||
mWebServer.bRunning = FALSE;
|
||||
|
||||
//
|
||||
// Send the page header
|
||||
//
|
||||
Status = HttpPageHeader ( SocketFD, pPort, L"Exit" );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Send the page body
|
||||
//
|
||||
Status = HttpSendAnsiString ( SocketFD,
|
||||
pPort,
|
||||
"<h1>Exit</h1>\r\n"
|
||||
"<p>\r\n"
|
||||
" Exiting the web-server application.\r\n"
|
||||
"</p>\r\n" );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Send the page trailer
|
||||
//
|
||||
Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the operation status
|
||||
//
|
||||
DBG_EXIT_STATUS ( Status );
|
||||
return Status;
|
||||
}
|
@@ -401,8 +401,8 @@ HttpPageTrailer (
|
||||
int RetVal;
|
||||
EFI_STATUS Status;
|
||||
socklen_t LengthInBytes;
|
||||
struct sockaddr_in LocalAddress;
|
||||
struct sockaddr_in RemoteAddress;
|
||||
struct sockaddr_in6 LocalAddress;
|
||||
struct sockaddr_in6 RemoteAddress;
|
||||
|
||||
DBG_ENTER ( );
|
||||
|
||||
@@ -413,12 +413,13 @@ HttpPageTrailer (
|
||||
LengthInBytes = sizeof ( LocalAddress );
|
||||
RetVal = getsockname ( SocketFD, (struct sockaddr *)&LocalAddress, &LengthInBytes );
|
||||
if ( 0 == RetVal ) {
|
||||
LengthInBytes = sizeof ( LocalAddress );
|
||||
RetVal = getpeername ( SocketFD, (struct sockaddr *)&RemoteAddress, &LengthInBytes );
|
||||
if ( 0 == RetVal ) {
|
||||
//
|
||||
// Seperate the body from the trailer
|
||||
//
|
||||
Status = HttpSendAnsiString ( SocketFD, pPort, " <hr>\r\n" );
|
||||
Status = HttpSendAnsiString ( SocketFD, pPort, " <hr>\r\n<code>" );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
@@ -438,7 +439,7 @@ HttpPageTrailer (
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
Status = HttpSendAnsiString ( SocketFD, pPort, "\r\n" );
|
||||
Status = HttpSendAnsiString ( SocketFD, pPort, "</code>\r\n" );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
@@ -1213,7 +1214,7 @@ HttpSendHexBits (
|
||||
//
|
||||
Digit = (UINT32)(( Value >> Shift ) & 0xf );
|
||||
if ( 10 <= Digit ) {
|
||||
Digit += 'A' - '0' - 10;
|
||||
Digit += 'a' - '0' - 10;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1274,7 +1275,7 @@ HttpSendHexValue (
|
||||
//
|
||||
Digit = (UINT32)(( Value >> Shift ) & 0xf );
|
||||
if ( 10 <= Digit ) {
|
||||
Digit += 'A' - '0' - 10;
|
||||
Digit += 'a' - '0' - 10;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1305,6 +1306,112 @@ HttpSendHexValue (
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Output an IP6 address value to the HTML page
|
||||
|
||||
@param [in] SocketFD Socket file descriptor
|
||||
@param [in] pPort The WSDT_PORT structure address
|
||||
@param [in] Value Value to display
|
||||
@param [in] bFirstValue TRUE if first value
|
||||
@param [in] bLastValue TRUE if last value
|
||||
@param [in] bZeroSuppression TRUE while zeros are being suppressed
|
||||
@param [in] pbZeroSuppression Address to receive TRUE when zero suppression
|
||||
has started, use NULL if next colon value not
|
||||
needed.
|
||||
|
||||
@retval EFI_SUCCESS Successfully displayed the address
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpSendIp6Value (
|
||||
IN int SocketFD,
|
||||
IN WSDT_PORT * pPort,
|
||||
IN UINT16 Value,
|
||||
IN BOOLEAN bFirstValue,
|
||||
IN BOOLEAN bLastValue,
|
||||
IN BOOLEAN bZeroSuppression,
|
||||
IN BOOLEAN * pbZeroSuppression
|
||||
)
|
||||
{
|
||||
BOOLEAN bZeroSuppressionStarting;
|
||||
UINT32 Digit;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Use break instead of goto
|
||||
//
|
||||
bZeroSuppressionStarting = FALSE;
|
||||
Status = EFI_SUCCESS;
|
||||
for ( ; ; ) {
|
||||
//
|
||||
// Display the leading colon if necessary
|
||||
//
|
||||
if ( bZeroSuppression && ( bLastValue || ( 0 != Value ))) {
|
||||
Status = HttpSendByte ( SocketFD, pPort, ':' );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Skip over a series of zero values
|
||||
//
|
||||
bZeroSuppressionStarting = (BOOLEAN)( 0 == Value );
|
||||
if ( !bZeroSuppressionStarting ) {
|
||||
//
|
||||
// Display the value
|
||||
//
|
||||
Digit = ( Value >> 4 ) & 0xf;
|
||||
Status = HttpSendHexValue ( SocketFD,
|
||||
pPort,
|
||||
Digit );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
Digit = Value & 0xf;
|
||||
Status = HttpSendHexValue ( SocketFD,
|
||||
pPort,
|
||||
Digit );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
Digit = ( Value >> 12 ) & 0xf;
|
||||
Status = HttpSendHexValue ( SocketFD,
|
||||
pPort,
|
||||
Digit );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
Digit = ( Value >> 8 ) & 0xf;
|
||||
Status = HttpSendHexValue ( SocketFD,
|
||||
pPort,
|
||||
Digit );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Display the trailing colon if necessary
|
||||
//
|
||||
if (( !bLastValue ) && ( bFirstValue || ( 0 != Value ))) {
|
||||
Status = HttpSendByte ( SocketFD, pPort, ':' );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the next colon display
|
||||
if ( NULL != pbZeroSuppression ) {
|
||||
*pbZeroSuppression = bZeroSuppressionStarting;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the operation status
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Output an IP address to the HTML page
|
||||
|
||||
@@ -1318,41 +1425,109 @@ EFI_STATUS
|
||||
HttpSendIpAddress (
|
||||
IN int SocketFD,
|
||||
IN WSDT_PORT * pPort,
|
||||
IN struct sockaddr_in * pAddress
|
||||
IN struct sockaddr_in6 * pAddress
|
||||
)
|
||||
{
|
||||
BOOLEAN bZeroSuppression;
|
||||
UINT32 Index;
|
||||
struct sockaddr_in * pIpv4;
|
||||
struct sockaddr_in6 * pIpv6;
|
||||
UINT16 PortNumber;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Output the IPv4 address
|
||||
// Use break instead of goto
|
||||
//
|
||||
Status = HttpSendValue ( SocketFD, pPort, (UINT8)pAddress->sin_addr.s_addr );
|
||||
if ( !EFI_ERROR ( Status )) {
|
||||
Status = HttpSendByte ( SocketFD, pPort, '.' );
|
||||
if ( !EFI_ERROR ( Status )) {
|
||||
Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pAddress->sin_addr.s_addr >> 8 ));
|
||||
if ( !EFI_ERROR ( Status )) {
|
||||
Status = HttpSendByte ( SocketFD, pPort, '.' );
|
||||
if ( !EFI_ERROR ( Status )) {
|
||||
Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pAddress->sin_addr.s_addr >> 16 ));
|
||||
if ( !EFI_ERROR ( Status )) {
|
||||
Status = HttpSendByte ( SocketFD, pPort, '.' );
|
||||
if ( !EFI_ERROR ( Status )) {
|
||||
Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pAddress->sin_addr.s_addr >> 24 ));
|
||||
if ( !EFI_ERROR ( Status )) {
|
||||
//
|
||||
// Output the port number
|
||||
//
|
||||
Status = HttpSendByte ( SocketFD, pPort, ':' );
|
||||
if ( !EFI_ERROR ( Status )) {
|
||||
Status = HttpSendValue ( SocketFD, pPort, htons ( pAddress->sin_port ));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( ; ; ) {
|
||||
//
|
||||
// Determine the type of address
|
||||
//
|
||||
if ( AF_INET6 == pAddress->sin6_family ) {
|
||||
pIpv6 = pAddress;
|
||||
|
||||
//
|
||||
// Display the address in RFC2732 format
|
||||
//
|
||||
bZeroSuppression = FALSE;
|
||||
Status = HttpSendByte ( SocketFD, pPort, '[' );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
for ( Index = 0; 8 > Index; Index++ ) {
|
||||
Status = HttpSendIp6Value ( SocketFD,
|
||||
pPort,
|
||||
pIpv6->sin6_addr.__u6_addr.__u6_addr16[ Index ],
|
||||
(BOOLEAN)( 0 == Index ),
|
||||
(BOOLEAN)( 7 == Index ),
|
||||
bZeroSuppression,
|
||||
&bZeroSuppression );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Separate the port number
|
||||
//
|
||||
Status = HttpSendByte ( SocketFD, pPort, ']' );
|
||||
|
||||
//
|
||||
// Get the port number
|
||||
//
|
||||
PortNumber = pIpv6->sin6_port;
|
||||
}
|
||||
else {
|
||||
//
|
||||
// Output the IPv4 address
|
||||
//
|
||||
pIpv4 = (struct sockaddr_in *)pAddress;
|
||||
Status = HttpSendValue ( SocketFD, pPort, (UINT8)pIpv4->sin_addr.s_addr );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
Status = HttpSendByte ( SocketFD, pPort, '.' );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pIpv4->sin_addr.s_addr >> 8 ));
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
Status = HttpSendByte ( SocketFD, pPort, '.' );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pIpv4->sin_addr.s_addr >> 16 ));
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
Status = HttpSendByte ( SocketFD, pPort, '.' );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pIpv4->sin_addr.s_addr >> 24 ));
|
||||
|
||||
//
|
||||
// Get the port number
|
||||
//
|
||||
PortNumber = pIpv4->sin_port;
|
||||
}
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Display the port number
|
||||
//
|
||||
Status = HttpSendByte ( SocketFD, pPort, ':' );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
Status = HttpSendValue ( SocketFD, pPort, htons ( PortNumber ));
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
|
@@ -44,10 +44,12 @@ CONST DT_PAGE mPageList[] = {
|
||||
{ L"/DhcpOptions", DhcpOptionsPage, L"DHCP Options" }, ///< Display the DHCP options
|
||||
{ PAGE_ACPI_DSDT, AcpiDsdtPage, L"DSDT - Differentiated System Description Table" }, ///< Format DSDT
|
||||
{ PAGE_DXE_SERVICES_TABLE, DxeServicesTablePage, L"DXE Services Table" }, ///< Format DXE services table
|
||||
{ L"/Exit", ExitPage, L"Exit the web server" }, ///< Exit the web server application
|
||||
{ PAGE_ACPI_FADT, AcpiFadtPage, L"FADT - Fixed ACPI Description Table" }, ///< Format FADT
|
||||
{ L"/Firmware", FirmwarePage, L"Firmware" }, ///< Firmware status
|
||||
{ L"/Handles", HandlePage, L"Display handles and associated protocol GUIDs" }, ///< Handle database page
|
||||
{ L"/Hello", HelloPage, L"Hello World" }, ///< Hello world page
|
||||
{ L"/Ports", PortsPage, L"Display web-server ports" },///< Web-server ports page
|
||||
{ L"/Reboot", RebootPage, L"Reboot the sytem" }, ///< Reboot page
|
||||
{ PAGE_ACPI_RSDP_10B, AcpiRsdp10Page, L"RSDP 1.0b - ACPI Root System Description Pointer" }, ///< Format RSDP 1.0b table
|
||||
{ PAGE_ACPI_RSDP_30, AcpiRsdp30Page, L"RSDP 3.0 - ACPI Root System Description Pointer" }, ///< Format RSDP 3.0 table
|
||||
|
146
AppPkg/Applications/Sockets/WebServer/Ports.c
Normal file
146
AppPkg/Applications/Sockets/WebServer/Ports.c
Normal file
@@ -0,0 +1,146 @@
|
||||
/*++
|
||||
This file contains an 'Intel UEFI Application' and is
|
||||
licensed for Intel CPUs and chipsets under the terms of your
|
||||
license agreement with Intel or your vendor. This file may
|
||||
be modified by the user, subject to additional terms of the
|
||||
license agreement
|
||||
--*/
|
||||
/*++
|
||||
|
||||
Copyright (c) 2011 Intel Corporation. All rights reserved
|
||||
This software and associated documentation (if any) is furnished
|
||||
under a license and may only be used or copied in accordance
|
||||
with the terms of the license. Except as permitted by such
|
||||
license, no part of this software or documentation may be
|
||||
reproduced, stored in a retrieval system, or transmitted in any
|
||||
form or by any means without the express written consent of
|
||||
Intel Corporation.
|
||||
|
||||
--*/
|
||||
|
||||
/** @file
|
||||
Ports response page
|
||||
|
||||
**/
|
||||
|
||||
#include <WebServer.h>
|
||||
|
||||
|
||||
/**
|
||||
Respond with the Ports page
|
||||
|
||||
@param [in] SocketFD The socket's file descriptor to add to the list.
|
||||
@param [in] pPort The WSDT_PORT structure address
|
||||
@param [out] pbDone Address to receive the request completion status
|
||||
|
||||
@retval EFI_SUCCESS The request was successfully processed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
PortsPage (
|
||||
IN int SocketFD,
|
||||
IN WSDT_PORT * pPort,
|
||||
OUT BOOLEAN * pbDone
|
||||
)
|
||||
{
|
||||
socklen_t AddressLength;
|
||||
struct sockaddr_in6 LocalAddress;
|
||||
DT_WEB_SERVER * pWebServer;
|
||||
EFI_STATUS Status;
|
||||
|
||||
DBG_ENTER ( );
|
||||
|
||||
//
|
||||
// Send the Hello World page
|
||||
//
|
||||
pWebServer = &mWebServer;
|
||||
for ( ; ; ) {
|
||||
//
|
||||
// Send the page header
|
||||
//
|
||||
Status = HttpPageHeader ( SocketFD, pPort, L"Ports" );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Send the page body
|
||||
//
|
||||
Status = HttpSendAnsiString ( SocketFD,
|
||||
pPort,
|
||||
"<h1>Web-Server Ports</h1>\r\n" );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for TCP v4
|
||||
//
|
||||
if ( -1 != pWebServer->HttpListenPort ) {
|
||||
AddressLength = sizeof ( LocalAddress );
|
||||
if ( 0 == getsockname ( pWebServer->HttpListenPort,
|
||||
(struct sockaddr *)&LocalAddress,
|
||||
&AddressLength )) {
|
||||
Status = HttpSendAnsiString ( SocketFD,
|
||||
pPort,
|
||||
"<a href=\"http://" );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
Status = HttpSendIpAddress ( SocketFD,
|
||||
pPort,
|
||||
&LocalAddress );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
Status = HttpSendAnsiString ( SocketFD,
|
||||
pPort,
|
||||
"\">Tcp4</a><br>\r\n" );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check for TCP v6
|
||||
//
|
||||
if ( -1 != pWebServer->HttpListenPort6 ) {
|
||||
AddressLength = sizeof ( LocalAddress );
|
||||
if ( 0 == getsockname ( pWebServer->HttpListenPort6,
|
||||
(struct sockaddr *)&LocalAddress,
|
||||
&AddressLength )) {
|
||||
Status = HttpSendAnsiString ( SocketFD,
|
||||
pPort,
|
||||
"<a href=\"http://" );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
Status = HttpSendIpAddress ( SocketFD,
|
||||
pPort,
|
||||
&LocalAddress );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
Status = HttpSendAnsiString ( SocketFD,
|
||||
pPort,
|
||||
"\">Tcp6</a><br>\r\n" );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Send the page trailer
|
||||
//
|
||||
Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the operation status
|
||||
//
|
||||
DBG_EXIT_STATUS ( Status );
|
||||
return Status;
|
||||
}
|
@@ -337,7 +337,7 @@ PortWork (
|
||||
size_t LengthInBytes;
|
||||
int NewSocket;
|
||||
EFI_STATUS OpStatus;
|
||||
struct sockaddr RemoteAddress;
|
||||
struct sockaddr_in6 RemoteAddress;
|
||||
socklen_t RemoteAddressLength;
|
||||
EFI_STATUS Status;
|
||||
|
||||
@@ -355,14 +355,15 @@ PortWork (
|
||||
//
|
||||
// Determine if this is a connection attempt
|
||||
//
|
||||
if ( SocketFD == pWebServer->HttpListenPort ) {
|
||||
if (( SocketFD == pWebServer->HttpListenPort )
|
||||
|| ( SocketFD == pWebServer->HttpListenPort6 )) {
|
||||
//
|
||||
// Handle connection attempts
|
||||
// Accepts arrive as read events
|
||||
//
|
||||
RemoteAddressLength = sizeof ( RemoteAddress );
|
||||
NewSocket = accept ( SocketFD,
|
||||
&RemoteAddress,
|
||||
(struct sockaddr *)&RemoteAddress,
|
||||
&RemoteAddressLength );
|
||||
if ( -1 != NewSocket ) {
|
||||
if ( 0 != NewSocket ) {
|
||||
@@ -561,9 +562,9 @@ SocketPoll (
|
||||
|
||||
|
||||
/**
|
||||
Create the HTTP port for the web server
|
||||
Create an HTTP port for the web server
|
||||
|
||||
This routine polls the network layer to create the HTTP port for the
|
||||
This routine polls the network layer to create an HTTP port for the
|
||||
web server. More than one attempt may be necessary since it may take
|
||||
some time to get the IP address and initialize the upper layers of
|
||||
the network stack.
|
||||
@@ -572,195 +573,93 @@ SocketPoll (
|
||||
coming and going of the network connections until the last network
|
||||
connection is broken.
|
||||
|
||||
@param [in] pWebServer The web server control structure address.
|
||||
@param [in] pWebServer The web server control structure address.
|
||||
@param [in] AddressFamily Address family for the network connection
|
||||
@param [in] Protocol Protocol to use for the network connection
|
||||
@param [in] HttpPort Port number for the HTTP connection
|
||||
@param [out] pPort Address of the port
|
||||
|
||||
**/
|
||||
VOID
|
||||
WebServerTimer (
|
||||
IN DT_WEB_SERVER * pWebServer
|
||||
WebServerListen (
|
||||
IN DT_WEB_SERVER * pWebServer,
|
||||
IN sa_family_t AddressFamily,
|
||||
IN int Protocol,
|
||||
IN UINT16 HttpPort,
|
||||
OUT int * pPort
|
||||
)
|
||||
{
|
||||
UINT16 HttpPort;
|
||||
struct sockaddr_in WebServerAddress;
|
||||
union {
|
||||
struct sockaddr_in v4;
|
||||
struct sockaddr_in6 v6;
|
||||
} WebServerAddress;
|
||||
int SocketStatus;
|
||||
EFI_STATUS Status;
|
||||
|
||||
DEBUG (( DEBUG_SERVER_TIMER, "Entering WebServerTimer\r\n" ));
|
||||
DEBUG (( DEBUG_SERVER_LISTEN, "Entering WebServerListen\r\n" ));
|
||||
|
||||
//
|
||||
// Open the HTTP port on the server
|
||||
// Attempt to create the socket for the web server
|
||||
//
|
||||
do {
|
||||
do {
|
||||
//
|
||||
// Complete the client operations
|
||||
//
|
||||
SocketPoll ( pWebServer );
|
||||
|
||||
//
|
||||
// Wait for a while
|
||||
//
|
||||
Status = gBS->CheckEvent ( pWebServer->TimerEvent );
|
||||
} while ( EFI_SUCCESS != Status );
|
||||
* pPort = socket ( AddressFamily, SOCK_STREAM, Protocol );
|
||||
if ( -1 != *pPort ) {
|
||||
//
|
||||
// Build the socket address
|
||||
//
|
||||
ZeroMem ( &WebServerAddress, sizeof ( WebServerAddress ));
|
||||
if ( AF_INET == AddressFamily ) {
|
||||
WebServerAddress.v4.sin_len = sizeof ( WebServerAddress.v4 );
|
||||
WebServerAddress.v4.sin_family = AddressFamily;
|
||||
WebServerAddress.v4.sin_port = htons ( HttpPort );
|
||||
}
|
||||
else {
|
||||
WebServerAddress.v6.sin6_len = sizeof ( WebServerAddress.v6 );
|
||||
WebServerAddress.v6.sin6_family = AddressFamily;
|
||||
WebServerAddress.v6.sin6_port = htons ( HttpPort );
|
||||
WebServerAddress.v6.sin6_scope_id = __IPV6_ADDR_SCOPE_GLOBAL;
|
||||
}
|
||||
|
||||
//
|
||||
// Attempt to create the socket for the web server
|
||||
// Bind the socket to the HTTP port
|
||||
//
|
||||
pWebServer->HttpListenPort = socket ( AF_INET,
|
||||
SOCK_STREAM,
|
||||
IPPROTO_TCP );
|
||||
if ( -1 != pWebServer->HttpListenPort ) {
|
||||
SocketStatus = bind ( *pPort,
|
||||
(struct sockaddr *) &WebServerAddress,
|
||||
WebServerAddress.v4.sin_len );
|
||||
if ( -1 != SocketStatus ) {
|
||||
//
|
||||
// Set the socket address
|
||||
// Enable connections to the HTTP port
|
||||
//
|
||||
ZeroMem ( &WebServerAddress, sizeof ( WebServerAddress ));
|
||||
HttpPort = PcdGet16 ( WebServer_HttpPort );
|
||||
DEBUG (( DEBUG_HTTP_PORT,
|
||||
"HTTP Port: %d\r\n",
|
||||
HttpPort ));
|
||||
WebServerAddress.sin_len = sizeof ( WebServerAddress );
|
||||
WebServerAddress.sin_family = AF_INET;
|
||||
WebServerAddress.sin_addr.s_addr = INADDR_ANY;
|
||||
WebServerAddress.sin_port = htons ( HttpPort );
|
||||
|
||||
//
|
||||
// Bind the socket to the HTTP port
|
||||
//
|
||||
SocketStatus = bind ( pWebServer->HttpListenPort,
|
||||
(struct sockaddr *) &WebServerAddress,
|
||||
WebServerAddress.sin_len );
|
||||
SocketStatus = listen ( *pPort, SOMAXCONN );
|
||||
if ( -1 != SocketStatus ) {
|
||||
//
|
||||
// Enable connections to the HTTP port
|
||||
// Add the HTTP port to the list of ports to poll
|
||||
//
|
||||
SocketStatus = listen ( pWebServer->HttpListenPort,
|
||||
SOMAXCONN );
|
||||
}
|
||||
|
||||
//
|
||||
// Release the socket if necessary
|
||||
//
|
||||
if ( -1 == SocketStatus ) {
|
||||
close ( pWebServer->HttpListenPort );
|
||||
pWebServer->HttpListenPort = -1;
|
||||
Status = PortAdd ( pWebServer, *pPort );
|
||||
if ( EFI_ERROR ( Status )) {
|
||||
SocketStatus = -1;
|
||||
}
|
||||
else {
|
||||
DEBUG (( DEBUG_PORT_WORK,
|
||||
"Listening on Tcp%d:%d\r\n",
|
||||
( AF_INET == AddressFamily ) ? 4 : 6,
|
||||
HttpPort ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Wait until the socket is open
|
||||
// Release the socket if necessary
|
||||
//
|
||||
}while ( -1 == pWebServer->HttpListenPort );
|
||||
|
||||
DEBUG (( DEBUG_SERVER_TIMER, "Exiting WebServerTimer\r\n" ));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Start the web server port creation timer
|
||||
|
||||
@param [in] pWebServer The web server control structure address.
|
||||
|
||||
@retval EFI_SUCCESS The timer was successfully started.
|
||||
@retval EFI_ALREADY_STARTED The timer is already running.
|
||||
@retval Other The timer failed to start.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
WebServerTimerStart (
|
||||
IN DT_WEB_SERVER * pWebServer
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT64 TriggerTime;
|
||||
|
||||
DBG_ENTER ( );
|
||||
|
||||
//
|
||||
// Assume the timer is already running
|
||||
//
|
||||
Status = EFI_ALREADY_STARTED;
|
||||
if ( !pWebServer->bTimerRunning ) {
|
||||
//
|
||||
// Compute the poll interval
|
||||
//
|
||||
TriggerTime = HTTP_PORT_POLL_DELAY * ( 1000 * 10 );
|
||||
Status = gBS->SetTimer ( pWebServer->TimerEvent,
|
||||
TimerPeriodic,
|
||||
TriggerTime );
|
||||
if ( !EFI_ERROR ( Status )) {
|
||||
DEBUG (( DEBUG_HTTP_PORT, "HTTP port timer started\r\n" ));
|
||||
|
||||
//
|
||||
// Mark the timer running
|
||||
//
|
||||
pWebServer->bTimerRunning = TRUE;
|
||||
}
|
||||
else {
|
||||
DEBUG (( DEBUG_ERROR | DEBUG_HTTP_PORT,
|
||||
"ERROR - Failed to start HTTP port timer, Status: %r\r\n",
|
||||
Status ));
|
||||
if ( -1 == SocketStatus ) {
|
||||
close ( *pPort );
|
||||
*pPort = -1;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Return the operation status
|
||||
//
|
||||
DBG_EXIT_STATUS ( Status );
|
||||
return Status;
|
||||
DEBUG (( DEBUG_SERVER_LISTEN, "Exiting WebServerListen\r\n" ));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Stop the web server port creation timer
|
||||
|
||||
@param [in] pWebServer The web server control structure address.
|
||||
|
||||
@retval EFI_SUCCESS The HTTP port timer is stopped
|
||||
@retval Other Failed to stop the HTTP port timer
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
WebServerTimerStop (
|
||||
IN DT_WEB_SERVER * pWebServer
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
DBG_ENTER ( );
|
||||
|
||||
//
|
||||
// Assume the timer is stopped
|
||||
//
|
||||
Status = EFI_SUCCESS;
|
||||
if ( pWebServer->bTimerRunning ) {
|
||||
//
|
||||
// Stop the port creation polling
|
||||
//
|
||||
Status = gBS->SetTimer ( pWebServer->TimerEvent,
|
||||
TimerCancel,
|
||||
0 );
|
||||
if ( !EFI_ERROR ( Status )) {
|
||||
DEBUG (( DEBUG_HTTP_PORT, "HTTP port timer stopped\r\n" ));
|
||||
|
||||
//
|
||||
// Mark the timer stopped
|
||||
//
|
||||
pWebServer->bTimerRunning = FALSE;
|
||||
}
|
||||
else {
|
||||
DEBUG (( DEBUG_ERROR | DEBUG_HTTP_PORT,
|
||||
"ERROR - Failed to stop HTTP port timer, Status: %r\r\n",
|
||||
Status ));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Return the operation status
|
||||
//
|
||||
DBG_EXIT_STATUS ( Status );
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Entry point for the web server application.
|
||||
|
||||
@@ -776,8 +675,19 @@ main (
|
||||
IN char **Argv
|
||||
)
|
||||
{
|
||||
UINT16 HttpPort;
|
||||
UINTN Index;
|
||||
DT_WEB_SERVER * pWebServer;
|
||||
EFI_STATUS Status;
|
||||
UINT64 TriggerTime;
|
||||
|
||||
//
|
||||
// Get the HTTP port
|
||||
//
|
||||
HttpPort = PcdGet16 ( WebServer_HttpPort );
|
||||
DEBUG (( DEBUG_HTTP_PORT,
|
||||
"HTTP Port: %d\r\n",
|
||||
HttpPort ));
|
||||
|
||||
//
|
||||
// Create a timer event to start HTTP port
|
||||
@@ -789,12 +699,18 @@ main (
|
||||
NULL,
|
||||
&pWebServer->TimerEvent );
|
||||
if ( !EFI_ERROR ( Status )) {
|
||||
Status = WebServerTimerStart ( pWebServer );
|
||||
TriggerTime = HTTP_PORT_POLL_DELAY * ( 1000 * 10 );
|
||||
Status = gBS->SetTimer ( pWebServer->TimerEvent,
|
||||
TimerPeriodic,
|
||||
TriggerTime );
|
||||
if ( !EFI_ERROR ( Status )) {
|
||||
//
|
||||
// Run the web server forever
|
||||
//
|
||||
for ( ; ; ) {
|
||||
pWebServer->HttpListenPort = -1;
|
||||
pWebServer->HttpListenPort6 = -1;
|
||||
pWebServer->bRunning = TRUE;
|
||||
do {
|
||||
//
|
||||
// Poll the network layer to create the HTTP port
|
||||
// for the web server. More than one attempt may
|
||||
@@ -802,45 +718,72 @@ main (
|
||||
// the IP address and initialize the upper layers
|
||||
// of the network stack.
|
||||
//
|
||||
WebServerTimer ( pWebServer );
|
||||
|
||||
//
|
||||
// Add the HTTP port to the list of ports
|
||||
//
|
||||
Status = PortAdd ( pWebServer, pWebServer->HttpListenPort );
|
||||
if ( !EFI_ERROR ( Status )) {
|
||||
//
|
||||
// Poll the sockets for activity
|
||||
//
|
||||
if (( -1 == pWebServer->HttpListenPort )
|
||||
|| ( -1 == pWebServer->HttpListenPort6 )) {
|
||||
do {
|
||||
SocketPoll ( pWebServer );
|
||||
} while ( -1 != pWebServer->HttpListenPort );
|
||||
//
|
||||
// Wait a while before polling for a connection
|
||||
//
|
||||
if ( EFI_SUCCESS != gBS->CheckEvent ( pWebServer->TimerEvent )) {
|
||||
if ( 0 != pWebServer->Entries ) {
|
||||
break;
|
||||
}
|
||||
gBS->WaitForEvent ( 1, &pWebServer->TimerEvent, &Index );
|
||||
}
|
||||
|
||||
//
|
||||
// The HTTP port failed the accept and was closed
|
||||
//
|
||||
//
|
||||
// Poll for a network connection
|
||||
//
|
||||
if ( -1 == pWebServer->HttpListenPort ) {
|
||||
WebServerListen ( pWebServer,
|
||||
AF_INET,
|
||||
IPPROTO_TCP,
|
||||
HttpPort,
|
||||
&pWebServer->HttpListenPort );
|
||||
}
|
||||
if ( -1 == pWebServer->HttpListenPort6 ) {
|
||||
WebServerListen ( pWebServer,
|
||||
AF_INET6,
|
||||
IPPROTO_TCP,
|
||||
HttpPort,
|
||||
&pWebServer->HttpListenPort6 );
|
||||
}
|
||||
|
||||
//
|
||||
// Continue polling while both network connections are
|
||||
// not present
|
||||
//
|
||||
} while ( 0 == pWebServer->Entries );
|
||||
}
|
||||
|
||||
//
|
||||
// Close the HTTP port if necessary
|
||||
// Poll the sockets for activity while both network
|
||||
// connections are connected
|
||||
//
|
||||
if ( -1 != pWebServer->HttpListenPort ) {
|
||||
close ( pWebServer->HttpListenPort );
|
||||
pWebServer->HttpListenPort = -1;
|
||||
}
|
||||
//
|
||||
// TODO: Remove the following test code
|
||||
// Exit when the network connection is broken
|
||||
//
|
||||
break;
|
||||
}
|
||||
do {
|
||||
SocketPoll ( pWebServer );
|
||||
} while ( pWebServer->bRunning
|
||||
&& ( -1 != pWebServer->HttpListenPort )
|
||||
&& ( -1 != pWebServer->HttpListenPort6 ));
|
||||
|
||||
//
|
||||
// Continue polling the network connections until both
|
||||
// TCP4 and TCP6 are connected
|
||||
//
|
||||
} while ( pWebServer->bRunning );
|
||||
|
||||
//
|
||||
// Done with the timer event
|
||||
// Stop the timer
|
||||
//
|
||||
WebServerTimerStop ( pWebServer );
|
||||
Status = gBS->CloseEvent ( pWebServer->TimerEvent );
|
||||
gBS->SetTimer ( pWebServer->TimerEvent,
|
||||
TimerCancel,
|
||||
0 );
|
||||
}
|
||||
|
||||
//
|
||||
// Done with the timer event
|
||||
//
|
||||
gBS->CloseEvent ( pWebServer->TimerEvent );
|
||||
}
|
||||
|
||||
//
|
||||
|
@@ -86,7 +86,7 @@
|
||||
|
||||
#define DEBUG_SOCKET_POLL 0x00080000 ///< Display the socket poll messages
|
||||
#define DEBUG_PORT_WORK 0x00040000 ///< Display the port work messages
|
||||
#define DEBUG_SERVER_TIMER 0x00020000 ///< Display the socket poll messages
|
||||
#define DEBUG_SERVER_LISTEN 0x00020000 ///< Display the socket poll messages
|
||||
#define DEBUG_HTTP_PORT 0x00010000 ///< Display HTTP port related messages
|
||||
#define DEBUG_REQUEST 0x00008000 ///< Display the HTTP request messages
|
||||
|
||||
@@ -173,9 +173,10 @@ typedef struct {
|
||||
//
|
||||
// HTTP port management
|
||||
//
|
||||
BOOLEAN bTimerRunning; ///< Port creation timer status
|
||||
BOOLEAN bRunning; ///< Web server running
|
||||
EFI_EVENT TimerEvent; ///< Timer to open HTTP port
|
||||
int HttpListenPort; ///< File descriptor for the HTTP listen port
|
||||
int HttpListenPort; ///< File descriptor for the HTTP listen port over TCP4
|
||||
int HttpListenPort6; ///< File descriptor for the HTTP listen port over TCP6
|
||||
|
||||
//
|
||||
// Client port management
|
||||
@@ -377,6 +378,23 @@ DxeServicesTablePage (
|
||||
OUT BOOLEAN * pbDone
|
||||
);
|
||||
|
||||
/**
|
||||
Respond with the Exit page
|
||||
|
||||
@param [in] SocketFD The socket's file descriptor to add to the list.
|
||||
@param [in] pPort The WSDT_PORT structure address
|
||||
@param [out] pbDone Address to receive the request completion status
|
||||
|
||||
@retval EFI_SUCCESS The request was successfully processed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ExitPage (
|
||||
IN int SocketFD,
|
||||
IN WSDT_PORT * pPort,
|
||||
OUT BOOLEAN * pbDone
|
||||
);
|
||||
|
||||
/**
|
||||
Respond with the firmware status
|
||||
|
||||
@@ -445,6 +463,23 @@ IndexPage (
|
||||
OUT BOOLEAN * pbDone
|
||||
);
|
||||
|
||||
/**
|
||||
Respond with the Ports page
|
||||
|
||||
@param [in] SocketFD The socket's file descriptor to add to the list.
|
||||
@param [in] pPort The WSDT_PORT structure address
|
||||
@param [out] pbDone Address to receive the request completion status
|
||||
|
||||
@retval EFI_SUCCESS The request was successfully processed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
PortsPage (
|
||||
IN int SocketFD,
|
||||
IN WSDT_PORT * pPort,
|
||||
OUT BOOLEAN * pbDone
|
||||
);
|
||||
|
||||
/**
|
||||
Page to reboot the system
|
||||
|
||||
@@ -723,7 +758,7 @@ EFI_STATUS
|
||||
HttpSendIpAddress (
|
||||
IN int SocketFD,
|
||||
IN WSDT_PORT * pPort,
|
||||
IN struct sockaddr_in * pAddress
|
||||
IN struct sockaddr_in6 * pAddress
|
||||
);
|
||||
|
||||
/**
|
||||
|
@@ -8,7 +8,7 @@
|
||||
# license agreement
|
||||
#
|
||||
#
|
||||
# Copyright (c) 20011 Intel Corporation. All rights reserved
|
||||
# Copyright (c) 2011 Intel Corporation. All rights reserved
|
||||
# This software and associated documentation (if any) is furnished
|
||||
# under a license and may only be used or copied in accordance
|
||||
# with the terms of the license. Except as permitted by such
|
||||
@@ -40,12 +40,14 @@
|
||||
ConfigurationTable.c
|
||||
DhcpOptions.c
|
||||
DxeServicesTable.c
|
||||
Exit.c
|
||||
Firmware.c
|
||||
Handles.c
|
||||
Hello.c
|
||||
HTTP.c
|
||||
Index.c
|
||||
PageList.c
|
||||
Ports.c
|
||||
Reboot.c
|
||||
RuntimeServicesTable.c
|
||||
SystemTable.c
|
||||
@@ -53,10 +55,10 @@
|
||||
|
||||
|
||||
[Pcd]
|
||||
gStdLibTokenSpaceGuid.WebServer_HttpPort
|
||||
|
||||
gAppPkgTokenSpaceGuid.WebServer_HttpPort
|
||||
|
||||
[Packages]
|
||||
AppPkg/AppPkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
ShellPkg/ShellPkg.dec
|
||||
@@ -68,14 +70,14 @@
|
||||
BsdSocketLib
|
||||
DebugLib
|
||||
DevShell
|
||||
# EfiSocketLib
|
||||
EfiSocketLib
|
||||
LibC
|
||||
ShellLib
|
||||
ShellCEntryLib
|
||||
UefiBootServicesTableLib
|
||||
UefiLib
|
||||
UefiRuntimeServicesTableLib
|
||||
UseSocketDxe
|
||||
# UseSocketDxe
|
||||
|
||||
[Guids]
|
||||
gEfiAcpi10TableGuid
|
||||
|
Reference in New Issue
Block a user