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:
lpleahy
2012-02-09 19:18:06 +00:00
parent 3bdf9aae5f
commit f6e5cdd5cf
34 changed files with 3524 additions and 1372 deletions

36
AppPkg/AppPkg.dec Normal file
View File

@ -0,0 +1,36 @@
## @file
# Declarations for the UDK Standard Libraries.
#
# Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available under
# the terms and conditions of the BSD License which accompanies this distribution.
# The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
##
[Defines]
DEC_SPECIFICATION = 0x00010005
PACKAGE_NAME = AppPkg
PACKAGE_GUID = B3E3D3D5-D62B-4497-A175-264F489D127E
PACKAGE_VERSION = 0.01
[Guids]
gAppPkgTokenSpaceGuid = { 0xe7e1efa6, 0x7607, 0x4a78, { 0xa7, 0xdd, 0x43, 0xe4, 0xbd, 0x72, 0xc0, 0x99 }}
[PcdsFixedAtBuild]
gAppPkgTokenSpaceGuid.DataSource_Port|1234|UINT16|0
gAppPkgTokenSpaceGuid.Tftp_AckLogBase|4|UINT32|1
gAppPkgTokenSpaceGuid.Tftp_AckMultiplier|4|UINT32|2
gAppPkgTokenSpaceGuid.Tftp_Bandwidth|0|BOOLEAN|3
gAppPkgTokenSpaceGuid.Tftp_HighSpeed|0|BOOLEAN|4
gAppPkgTokenSpaceGuid.Tftp_MaxRetry|10|UINT32|5
gAppPkgTokenSpaceGuid.Tftp_MaxTimeoutInSec|3|UINT32|6
gAppPkgTokenSpaceGuid.WebServer_HttpPort|80|UINT16|7

View File

@ -28,10 +28,12 @@
#include <sys/socket.h> #include <sys/socket.h>
#define MAX_CONNECTIONS ( 1 + 16 ) ///< Maximum number of client connections #define DATA_SAMPLE_SHIFT 5 ///< Shift for number of samples
#define RANGE_SWITCH 2048 ///< Switch display ranges #define MAX_CONNECTIONS ( 1 + 16 ) ///< Maximum number of client connections
#define DATA_RATE_UPDATE_SHIFT 2 ///< 2n seconds between updates #define RANGE_SWITCH ( 1024 * 1024 ) ///< Switch display ranges
#define DATA_RATE_UPDATE_SHIFT 2 ///< 2n seconds between updates
#define AVERAGE_SHIFT_COUNT ( 6 - DATA_RATE_UPDATE_SHIFT ) ///< 2n samples in average #define AVERAGE_SHIFT_COUNT ( 6 - DATA_RATE_UPDATE_SHIFT ) ///< 2n samples in average
#define DATA_SAMPLES ( 1 << DATA_SAMPLE_SHIFT ) ///< Number of samples
#define TPL_DATASINK TPL_CALLBACK ///< Synchronization TPL #define TPL_DATASINK TPL_CALLBACK ///< Synchronization TPL
@ -39,16 +41,16 @@
#define DATA_BUFFER_SIZE (( 65536 / PACKET_SIZE ) * PACKET_SIZE ) ///< Buffer size in bytes #define DATA_BUFFER_SIZE (( 65536 / PACKET_SIZE ) * PACKET_SIZE ) ///< Buffer size in bytes
typedef struct _DT_PORT { typedef struct _DT_PORT {
UINT64 BytesAverage;
UINT64 BytesPrevious;
UINT64 BytesTotal; UINT64 BytesTotal;
struct sockaddr_in RemoteAddress; struct sockaddr_in6 IpAddress;
UINT64 Samples; UINT32 In;
UINT32 Samples;
UINT64 BytesReceived[ DATA_SAMPLES ];
} DT_PORT; } DT_PORT;
volatile BOOLEAN bTick; volatile BOOLEAN bTick;
BOOLEAN bTimerRunning; BOOLEAN bTimerRunning;
struct sockaddr_in LocalAddress; struct sockaddr_in6 LocalAddress;
EFI_EVENT pTimer; EFI_EVENT pTimer;
int ListenSocket; int ListenSocket;
UINT8 Buffer[ DATA_BUFFER_SIZE ]; UINT8 Buffer[ DATA_BUFFER_SIZE ];
@ -120,7 +122,7 @@ SocketAccept (
// //
SocketStatus = bind ( ListenSocket, SocketStatus = bind ( ListenSocket,
(struct sockaddr *) &LocalAddress, (struct sockaddr *) &LocalAddress,
LocalAddress.sin_len ); LocalAddress.sin6_len );
if ( 0 == SocketStatus ) { if ( 0 == SocketStatus ) {
// //
// Start listening on the local socket // Start listening on the local socket
@ -139,14 +141,7 @@ SocketAccept (
PollFd[ Index ].fd = ListenSocket; PollFd[ Index ].fd = ListenSocket;
PollFd[ Index ].events = POLLRDNORM | POLLHUP; PollFd[ Index ].events = POLLRDNORM | POLLHUP;
PollFd[ Index ].revents = 0; PollFd[ Index ].revents = 0;
Port[ Index ].BytesAverage = 0; ZeroMem ( &Port[ Index ], sizeof ( Port[ Index ]));
Port[ Index ].BytesPrevious = 0;
Port[ Index ].BytesTotal = 0;
Port[ Index ].Samples = 0;
Port[ Index ].RemoteAddress.sin_len = 0;
Port[ Index ].RemoteAddress.sin_family = 0;
Port[ Index ].RemoteAddress.sin_port = 0;
Port[ Index ].RemoteAddress.sin_addr.s_addr= 0;
} }
} }
@ -203,11 +198,14 @@ SocketClose (
/** /**
Create the socket Create the socket
@param [in] Family Network family, AF_INET or AF_INET6
@retval EFI_SUCCESS The application is running normally @retval EFI_SUCCESS The application is running normally
@retval Other The user stopped the application @retval Other The user stopped the application
**/ **/
EFI_STATUS EFI_STATUS
SocketNew ( SocketNew (
sa_family_t Family
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -216,9 +214,9 @@ SocketNew (
// Get the port number // Get the port number
// //
ZeroMem ( &LocalAddress, sizeof ( LocalAddress )); ZeroMem ( &LocalAddress, sizeof ( LocalAddress ));
LocalAddress.sin_len = sizeof ( LocalAddress ); LocalAddress.sin6_len = sizeof ( LocalAddress );
LocalAddress.sin_family = AF_INET; LocalAddress.sin6_family = Family;
LocalAddress.sin_port = htons ( PcdGet16 ( DataSource_Port )); LocalAddress.sin6_port = htons ( PcdGet16 ( DataSource_Port ));
// //
// Loop creating the socket // Loop creating the socket
@ -234,7 +232,7 @@ SocketNew (
// //
// Attempt to create the socket // Attempt to create the socket
// //
ListenSocket = socket ( AF_INET, ListenSocket = socket ( LocalAddress.sin6_family,
SOCK_STREAM, SOCK_STREAM,
IPPROTO_TCP ); IPPROTO_TCP );
if ( -1 != ListenSocket ) { if ( -1 != ListenSocket ) {
@ -274,7 +272,11 @@ SocketPoll (
int FdCount; int FdCount;
nfds_t Index; nfds_t Index;
socklen_t LengthInBytes; socklen_t LengthInBytes;
struct sockaddr_in RemoteAddress; struct sockaddr_in * pPortIpAddress4;
struct sockaddr_in6 * pPortIpAddress6;
struct sockaddr_in * pRemoteAddress4;
struct sockaddr_in6 * pRemoteAddress6;
struct sockaddr_in6 RemoteAddress;
int Socket; int Socket;
EFI_STATUS Status; EFI_STATUS Status;
EFI_TPL TplPrevious; EFI_TPL TplPrevious;
@ -282,6 +284,8 @@ SocketPoll (
// //
// Check for control-C // Check for control-C
// //
pRemoteAddress4 = (struct sockaddr_in *)&RemoteAddress;
pRemoteAddress6 = (struct sockaddr_in6 *)&RemoteAddress;
bListenError = FALSE; bListenError = FALSE;
Status = ControlCCheck ( ); Status = ControlCCheck ( );
if ( !EFI_ERROR ( Status )) { if ( !EFI_ERROR ( Status )) {
@ -311,6 +315,8 @@ SocketPoll (
// //
// Account for this descriptor // Account for this descriptor
// //
pPortIpAddress4 = (struct sockaddr_in *)&Port[ Index ].IpAddress;
pPortIpAddress6 = (struct sockaddr_in6 *)&Port[ Index ].IpAddress;
if ( 0 != PollFd[ Index ].revents ) { if ( 0 != PollFd[ Index ].revents ) {
FdCount -= 1; FdCount -= 1;
} }
@ -327,14 +333,38 @@ SocketPoll (
errno )); errno ));
} }
else { else {
DEBUG (( DEBUG_ERROR, if ( AF_INET == pPortIpAddress4->sin_family ) {
"ERROR - Network closed on socket %d.%d.%d.%d:%d, errno: %d\r\n", DEBUG (( DEBUG_ERROR,
Port[ Index ].RemoteAddress.sin_addr.s_addr & 0xff, "ERROR - Network closed on socket %d.%d.%d.%d:%d, errno: %d\r\n",
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff, pPortIpAddress4->sin_addr.s_addr & 0xff,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff, ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff, ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
htons ( Port[ Index ].RemoteAddress.sin_port ), ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
errno )); htons ( pPortIpAddress4->sin_port ),
errno ));
}
else {
DEBUG (( DEBUG_ERROR,
"ERROR - Network closed on socket [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
htons ( pPortIpAddress6->sin6_port ),
errno ));
}
// //
// Close the socket // Close the socket
@ -342,25 +372,74 @@ SocketPoll (
CloseStatus = close ( PollFd[ Index ].fd ); CloseStatus = close ( PollFd[ Index ].fd );
if ( 0 == CloseStatus ) { if ( 0 == CloseStatus ) {
bRemoveSocket = TRUE; bRemoveSocket = TRUE;
DEBUG (( DEBUG_INFO, if ( AF_INET == pPortIpAddress4->sin_family ) {
"0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n", DEBUG (( DEBUG_INFO,
PollFd[ Index ].fd, "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",
Port[ Index ].RemoteAddress.sin_addr.s_addr & 0xff, PollFd[ Index ].fd,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff, pPortIpAddress4->sin_addr.s_addr & 0xff,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff, ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff, ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
htons ( Port[ Index ].RemoteAddress.sin_port ))); ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
htons ( pPortIpAddress4->sin_port )));
}
else {
DEBUG (( DEBUG_INFO,
"0x%08x: Socket closed for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
PollFd[ Index ].fd,
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
htons ( pPortIpAddress6->sin6_port )));
}
} }
else { else {
DEBUG (( DEBUG_ERROR, if ( AF_INET == pPortIpAddress4->sin_family ) {
"ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n", DEBUG (( DEBUG_ERROR,
PollFd[ Index ].fd, "ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n",
Port[ Index ].RemoteAddress.sin_addr.s_addr & 0xff, PollFd[ Index ].fd,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff, pPortIpAddress4->sin_addr.s_addr & 0xff,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff, ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff, ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
htons ( Port[ Index ].RemoteAddress.sin_port ), ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
errno )); htons ( pPortIpAddress4->sin_port ),
errno ));
}
else {
DEBUG (( DEBUG_ERROR,
"ERROR - Failed to close socket 0x%08x for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",
PollFd[ Index ].fd,
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
htons ( pPortIpAddress6->sin6_port ),
errno ));
}
} }
} }
} }
@ -399,12 +478,34 @@ SocketPoll (
// //
// Display the connection // Display the connection
// //
Print ( L"Rejecting connection to remote system %d.%d.%d.%d:%d\r\n", if ( AF_INET == pRemoteAddress4->sin_family ) {
RemoteAddress.sin_addr.s_addr & 0xff, Print ( L"Rejecting connection to remote system %d.%d.%d.%d:%d\r\n",
( RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff, pRemoteAddress4->sin_addr.s_addr & 0xff,
( RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff, ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,
( RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff, ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,
htons ( RemoteAddress.sin_port )); ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,
htons ( pRemoteAddress4->sin_port ));
}
else {
Print ( L"Rejecting connection to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
htons ( pRemoteAddress6->sin6_port ));
}
// //
// No room for this connection // No room for this connection
@ -413,14 +514,38 @@ SocketPoll (
CloseStatus = close ( Socket ); CloseStatus = close ( Socket );
if ( 0 == CloseStatus ) { if ( 0 == CloseStatus ) {
bRemoveSocket = TRUE; bRemoveSocket = TRUE;
DEBUG (( DEBUG_INFO, if ( AF_INET == pRemoteAddress4->sin_family ) {
"0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n", DEBUG (( DEBUG_INFO,
PollFd[ Index ].fd, "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",
RemoteAddress.sin_addr.s_addr & 0xff, PollFd[ Index ].fd,
( RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff, pRemoteAddress4->sin_addr.s_addr & 0xff,
( RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff, ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,
( RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff, ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,
htons ( RemoteAddress.sin_port ))); ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,
htons ( pRemoteAddress4->sin_port )));
}
else {
DEBUG (( DEBUG_INFO,
"0x%08x: Socket closed for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
PollFd[ Index ].fd,
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
htons ( pRemoteAddress6->sin6_port )));
}
} }
else { else {
DEBUG (( DEBUG_ERROR, DEBUG (( DEBUG_ERROR,
@ -439,25 +564,41 @@ SocketPoll (
// //
// Display the connection // Display the connection
// //
Print ( L"Connected to remote system %d.%d.%d.%d:%d\r\n", if ( AF_INET == pRemoteAddress4->sin_family ) {
RemoteAddress.sin_addr.s_addr & 0xff, Print ( L"Connected to remote system %d.%d.%d.%d:%d\r\n",
( RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff, pRemoteAddress4->sin_addr.s_addr & 0xff,
( RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff, ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,
( RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff, ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,
htons ( RemoteAddress.sin_port )); ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,
htons ( pRemoteAddress4->sin_port ));
}
else {
Print ( L"Connected to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
htons ( pRemoteAddress6->sin6_port ));
}
// //
// Allocate the client connection // Allocate the client connection
// //
Index = MaxPort++; Index = MaxPort++;
Port[ Index ].BytesAverage = 0; ZeroMem ( &Port[ Index ], sizeof ( Port[ Index ]));
Port[ Index ].BytesPrevious = 0; CopyMem ( pPortIpAddress6, pRemoteAddress6, sizeof ( *pRemoteAddress6 ));
Port[ Index ].BytesTotal = 0;
Port[ Index ].Samples = 0;
Port[ Index ].RemoteAddress.sin_len = RemoteAddress.sin_len;
Port[ Index ].RemoteAddress.sin_family = RemoteAddress.sin_family;
Port[ Index ].RemoteAddress.sin_port = RemoteAddress.sin_port;
Port[ Index ].RemoteAddress.sin_addr = RemoteAddress.sin_addr;
PollFd[ Index ].fd = Socket; PollFd[ Index ].fd = Socket;
PollFd[ Index ].events = POLLRDNORM | POLLHUP; PollFd[ Index ].events = POLLRDNORM | POLLHUP;
PollFd[ Index ].revents = 0; PollFd[ Index ].revents = 0;
@ -475,15 +616,40 @@ SocketPoll (
// //
// Display the amount of data received // Display the amount of data received
// //
DEBUG (( DEBUG_INFO, if ( AF_INET == pPortIpAddress4->sin_family ) {
"0x%08x: Socket received 0x%08x bytes from %d.%d.%d.%d:%d\r\n", DEBUG (( DEBUG_INFO,
PollFd[ Index ].fd, "0x%08x: Socket received 0x%08x bytes from %d.%d.%d.%d:%d\r\n",
BytesReceived, PollFd[ Index ].fd,
Port[ Index ].RemoteAddress.sin_addr.s_addr & 0xff, BytesReceived,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff, pPortIpAddress4->sin_addr.s_addr & 0xff,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff, ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff, ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
htons ( Port[ Index ].RemoteAddress.sin_port ))); ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
htons ( pPortIpAddress4->sin_port )));
}
else {
DEBUG (( DEBUG_INFO,
"0x%08x: Socket received 0x%08x bytes from [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
PollFd[ Index ].fd,
BytesReceived,
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
htons ( pPortIpAddress6->sin6_port )));
}
// //
// Synchronize with the TimerCallback routine // Synchronize with the TimerCallback routine
@ -504,36 +670,109 @@ SocketPoll (
// //
// Close the socket // Close the socket
// //
DEBUG (( DEBUG_INFO, if ( AF_INET == pPortIpAddress4->sin_family ) {
"ERROR - Receive failure for %d.%d.%d.%d:%d, errno: %d\r\n", DEBUG (( DEBUG_INFO,
Port[ Index ].RemoteAddress.sin_addr.s_addr & 0xff, "ERROR - Receive failure for %d.%d.%d.%d:%d, errno: %d\r\n",
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff, pPortIpAddress4->sin_addr.s_addr & 0xff,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff, ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff, ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
htons ( Port[ Index ].RemoteAddress.sin_port ), ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
errno )); htons ( pPortIpAddress4->sin_port ),
errno ));
}
else {
DEBUG (( DEBUG_INFO,
"ERROR - Receive failure for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
htons ( pPortIpAddress6->sin6_port ),
errno ));
}
CloseStatus = close ( PollFd[ Index ].fd ); CloseStatus = close ( PollFd[ Index ].fd );
if ( 0 == CloseStatus ) { if ( 0 == CloseStatus ) {
bRemoveSocket = TRUE; bRemoveSocket = TRUE;
DEBUG (( DEBUG_INFO, if ( AF_INET == pPortIpAddress4->sin_family ) {
"0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n", DEBUG (( DEBUG_INFO,
PollFd[ Index ].fd, "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",
Port[ Index ].RemoteAddress.sin_addr.s_addr & 0xff, PollFd[ Index ].fd,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff, pPortIpAddress4->sin_addr.s_addr & 0xff,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff, ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff, ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
htons ( Port[ Index ].RemoteAddress.sin_port ))); ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
htons ( pPortIpAddress4->sin_port )));
}
else {
DEBUG (( DEBUG_INFO,
"0x%08x: Socket closed for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
PollFd[ Index ].fd,
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
htons ( pPortIpAddress6->sin6_port )));
}
} }
else { else {
DEBUG (( DEBUG_ERROR, if ( AF_INET == pPortIpAddress4->sin_family ) {
"ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n", DEBUG (( DEBUG_ERROR,
PollFd[ Index ].fd, "ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n",
Port[ Index ].RemoteAddress.sin_addr.s_addr & 0xff, PollFd[ Index ].fd,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff, pPortIpAddress4->sin_addr.s_addr & 0xff,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff, ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,
( Port[ Index ].RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff, ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,
htons ( Port[ Index ].RemoteAddress.sin_port ), ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,
errno )); htons ( pPortIpAddress4->sin_port ),
errno ));
}
else {
DEBUG (( DEBUG_ERROR,
"ERROR - Failed to close socket 0x%08x for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",
PollFd[ Index ].fd,
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
htons ( pPortIpAddress6->sin6_port ),
errno ));
}
} }
} }
@ -555,14 +794,9 @@ SocketPoll (
MaxPort -= 1; MaxPort -= 1;
for ( Entry = Index + 1; MaxPort >= Entry; Entry++ ) { for ( Entry = Index + 1; MaxPort >= Entry; Entry++ ) {
EntryPrevious = Entry; EntryPrevious = Entry;
Port[ EntryPrevious ].BytesAverage = Port[ Entry ].BytesAverage; CopyMem ( &Port[ EntryPrevious ],
Port[ EntryPrevious ].BytesPrevious = Port[ Entry ].BytesPrevious; &Port[ Entry ],
Port[ EntryPrevious ].BytesTotal = Port[ Entry ].BytesTotal; sizeof ( Port[ Entry ]));
Port[ EntryPrevious ].RemoteAddress.sin_len = Port[ Entry ].RemoteAddress.sin_len;
Port[ EntryPrevious ].RemoteAddress.sin_family = Port[ Entry ].RemoteAddress.sin_family;
Port[ EntryPrevious ].RemoteAddress.sin_port = Port[ Entry ].RemoteAddress.sin_port;
Port[ EntryPrevious ].RemoteAddress.sin_addr.s_addr = Port[ Entry ].RemoteAddress.sin_addr.s_addr;
Port[ EntryPrevious ].Samples = Port[ Entry ].Samples;
PollFd[ EntryPrevious ].events = PollFd[ Entry ].events; PollFd[ EntryPrevious ].events = PollFd[ Entry ].events;
PollFd[ EntryPrevious ].fd = PollFd[ Entry ].fd; PollFd[ EntryPrevious ].fd = PollFd[ Entry ].fd;
PollFd[ EntryPrevious ].revents = PollFd[ Entry ].revents; PollFd[ EntryPrevious ].revents = PollFd[ Entry ].revents;
@ -605,11 +839,12 @@ TimerCallback (
IN VOID * pContext IN VOID * pContext
) )
{ {
UINT64 Average; UINT32 Average;
UINT64 BitsPerSecond;
UINT64 BytesReceived; UINT64 BytesReceived;
UINT32 Delta; UINT32 Count;
UINT64 DeltaBytes;
nfds_t Index; nfds_t Index;
UINT64 TotalBytes;
// //
// Notify the other code of the timer tick // Notify the other code of the timer tick
@ -627,65 +862,84 @@ TimerCallback (
if (( ListenSocket != PollFd[ Index ].fd ) if (( ListenSocket != PollFd[ Index ].fd )
&& ( 0 != BytesReceived )) { && ( 0 != BytesReceived )) {
// //
// Update the average bytes per second // Update the received data samples
// //
DeltaBytes = Port[ Index ].BytesAverage >> AVERAGE_SHIFT_COUNT; Port[ Index ].BytesTotal = 0;
Port[ Index ].BytesAverage -= DeltaBytes; Port[ Index ].BytesReceived [ Port[ Index ].In ] = BytesReceived;
DeltaBytes = BytesReceived - Port[ Index ].BytesPrevious; Port[ Index ].In += 1;
Port[ Index ].BytesPrevious = BytesReceived; if ( DATA_SAMPLES <= Port[ Index ].In ) {
Port[ Index ].BytesAverage += DeltaBytes; Port[ Index ].In = 0;
}
// //
// Separate the samples // Separate the samples
// //
if (( 2 << AVERAGE_SHIFT_COUNT ) == Port[ Index ].Samples ) { if ( DATA_SAMPLES == Port[ Index ].Samples ) {
Print ( L"---------- Stable average ----------\r\n" ); Print ( L"---------- Stable average ----------\r\n" );
} }
Port[ Index ].Samples += 1; Port[ Index ].Samples += 1;
//
// Compute the data rate
//
TotalBytes = 0;
for ( Count = 0; DATA_SAMPLES > Count; Count++ )
{
TotalBytes += Port[ Index ].BytesReceived[ Count ];
}
Average = (UINT32)RShiftU64 ( TotalBytes, DATA_SAMPLE_SHIFT );
BitsPerSecond = Average * 8;
// //
// Display the data rate // Display the data rate
// //
Delta = (UINT32)( DeltaBytes >> DATA_RATE_UPDATE_SHIFT ); if (( RANGE_SWITCH >> 10 ) > Average ) {
Average = Port[ Index ].BytesAverage >> ( AVERAGE_SHIFT_COUNT + DATA_RATE_UPDATE_SHIFT ); Print ( L"Ave: %d Bytes/Sec, %Ld Bits/sec\r\n",
if ( Average < RANGE_SWITCH ) { Average,
Print ( L"%d Bytes/sec, Ave: %d Bytes/Sec\r\n", BitsPerSecond );
Delta,
(UINT32) Average );
} }
else { else {
Average >>= 10; BitsPerSecond /= 1000;
if ( Average < RANGE_SWITCH ) { if ( RANGE_SWITCH > Average ) {
Print ( L"%d Bytes/sec, Ave: %d KiBytes/Sec\r\n", Print ( L"Ave: %d.%03d KiBytes/Sec, %Ld KBits/sec\r\n",
Delta, Average >> 10,
(UINT32) Average ); (( Average & 0x3ff ) * 1000 ) >> 10,
BitsPerSecond );
} }
else { else {
BitsPerSecond /= 1000;
Average >>= 10; Average >>= 10;
if ( Average < RANGE_SWITCH ) { if ( RANGE_SWITCH > Average ) {
Print ( L"%d Bytes/sec, Ave: %d MiBytes/Sec\r\n", Print ( L"Ave: %d.%03d MiBytes/Sec, %Ld MBits/sec\r\n",
Delta, Average >> 10,
(UINT32) Average ); (( Average & 0x3ff ) * 1000 ) >> 10,
BitsPerSecond );
} }
else { else {
BitsPerSecond /= 1000;
Average >>= 10; Average >>= 10;
if ( Average < RANGE_SWITCH ) { if ( RANGE_SWITCH > Average ) {
Print ( L"%d Bytes/sec, Ave: %d GiBytes/Sec\r\n", Print ( L"Ave: %d.%03d GiBytes/Sec, %Ld GBits/sec\r\n",
Delta, Average >> 10,
(UINT32) Average ); (( Average & 0x3ff ) * 1000 ) >> 10,
BitsPerSecond );
} }
else { else {
BitsPerSecond /= 1000;
Average >>= 10; Average >>= 10;
if ( Average < RANGE_SWITCH ) { if ( RANGE_SWITCH > Average ) {
Print ( L"%d Bytes/sec, Ave: %d TiBytes/Sec\r\n", Print ( L"Ave: %d.%03d TiBytes/Sec, %Ld TBits/sec\r\n",
Delta, Average >> 10,
Average ); (( Average & 0x3ff ) * 1000 ) >> 10,
BitsPerSecond );
} }
else { else {
BitsPerSecond /= 1000;
Average >>= 10; Average >>= 10;
Print ( L"%d Bytes/sec, Ave: %d PiBytes/Sec\r\n", Print ( L"Ave: %d.%03d PiBytes/Sec, %Ld PBits/sec\r\n",
Delta, Average >> 10,
(UINT32) Average ); (( Average & 0x3ff ) * 1000 ) >> 10,
BitsPerSecond );
} }
} }
} }
@ -909,11 +1163,17 @@ main (
IN char **Argv IN char **Argv
) )
{ {
sa_family_t Family;
EFI_STATUS Status; EFI_STATUS Status;
DEBUG (( DEBUG_INFO, DEBUG (( DEBUG_INFO,
"DataSink starting\r\n" )); "DataSink starting\r\n" ));
//
// Determine the family to use
//
Family = ( 1 < Argc ) ? AF_INET6 : AF_INET;
// //
// Use for/break instead of goto // Use for/break instead of goto
// //
@ -966,7 +1226,7 @@ main (
// //
// Wait for the network layer to initialize // Wait for the network layer to initialize
// //
Status = SocketNew ( ); Status = SocketNew ( Family );
if ( EFI_ERROR ( Status )) { if ( EFI_ERROR ( Status )) {
continue; continue;
} }
@ -987,7 +1247,7 @@ main (
} }
// //
// Send data until the connection breaks // Receive data until the connection breaks
// //
do { do {
Status = SocketPoll ( ); Status = SocketPoll ( );

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such
@ -39,10 +39,11 @@
[Pcd] [Pcd]
gStdLibTokenSpaceGuid.DataSource_Port gAppPkgTokenSpaceGuid.DataSource_Port
[Packages] [Packages]
AppPkg/AppPkg.dec
MdePkg/MdePkg.dec MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec ShellPkg/ShellPkg.dec
StdLib/StdLib.dec StdLib/StdLib.dec

View File

@ -30,10 +30,14 @@
#include <sys/poll.h> #include <sys/poll.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <stdio.h>
#define RANGE_SWITCH 2048 ///< Switch display ranges
#define DATA_RATE_UPDATE_SHIFT 2 ///< 2n seconds between updates #define DATA_SAMPLE_SHIFT 5 ///< Shift for number of samples
#define RANGE_SWITCH ( 1024 * 1024 ) ///< Switch display ranges
#define DATA_RATE_UPDATE_SHIFT 2 ///< 2n seconds between updates
#define AVERAGE_SHIFT_COUNT ( 6 - DATA_RATE_UPDATE_SHIFT ) ///< 2n samples in average #define AVERAGE_SHIFT_COUNT ( 6 - DATA_RATE_UPDATE_SHIFT ) ///< 2n samples in average
#define DATA_SAMPLES ( 1 << DATA_SAMPLE_SHIFT ) ///< Number of samples
#define TPL_DATASOURCE TPL_CALLBACK ///< Synchronization TPL #define TPL_DATASOURCE TPL_CALLBACK ///< Synchronization TPL
@ -74,16 +78,16 @@ EFI_EVENT pTimer;
// //
// Remote IP Address Data // Remote IP Address Data
// //
struct sockaddr_in RemoteHostAddress; struct sockaddr_in6 RemoteHostAddress;
CHAR8 * pRemoteHost; CHAR8 * pRemoteHost;
// //
// Traffic Data // Traffic Data
// //
UINT64 TotalBytesSent; UINT64 TotalBytesSent;
UINT64 PreviousBytes; UINT32 In;
UINT64 AverageBytes; UINT32 Samples;
UINT64 Samples; UINT64 BytesSent[ DATA_SAMPLES ];
UINT8 Buffer[ DATA_BUFFER_SIZE ]; UINT8 Buffer[ DATA_BUFFER_SIZE ];
@ -185,48 +189,124 @@ EFI_STATUS
IpAddress ( IpAddress (
) )
{ {
CHAR8 * pSeparator; struct sockaddr_in * pRemoteAddress4;
INT32 RemoteAddress; struct sockaddr_in6 * pRemoteAddress6;
UINT32 RemoteAddress;
EFI_STATUS Status; EFI_STATUS Status;
UINT32 Value1; UINT32 Value1;
UINT32 Value2; UINT32 Value2;
UINT32 Value3; UINT32 Value3;
UINT32 Value4; UINT32 Value4;
UINT32 Value5;
UINT32 Value6;
UINT32 Value7;
UINT32 Value8;
// //
// Assume failure // Assume failure
// //
Status = EFI_INVALID_PARAMETER; Status = EFI_INVALID_PARAMETER;
//
// Get the port number
//
ZeroMem ( &RemoteHostAddress, sizeof ( RemoteHostAddress ));
RemoteHostAddress.sin6_port = htons ( PcdGet16 ( DataSource_Port ));
pRemoteAddress4 = (struct sockaddr_in *)&RemoteHostAddress;
pRemoteAddress6 = &RemoteHostAddress;
// //
// Convert the IP address from a string to a numeric value // Convert the IP address from a string to a numeric value
// //
pSeparator = GetDigit ( pRemoteHost, &Value1 ); if (( 4 == sscanf ( pRemoteHost,
if (( 255 >= Value1 ) && ( '.' == *pSeparator )) { "%d.%d.%d.%d",
pSeparator = GetDigit ( ++pSeparator, &Value2 ); &Value1,
if (( 255 >= Value2 ) && ( '.' == *pSeparator )) { &Value2,
pSeparator = GetDigit ( ++pSeparator, &Value3 ); &Value3,
if (( 255 >= Value3 ) && ( '.' == *pSeparator )) { &Value4 ))
pSeparator = GetDigit ( ++pSeparator, &Value4 ); && ( 255 >= Value1 )
if (( 255 >= Value4 ) && ( 0 == *pSeparator )) { && ( 255 >= Value2 )
RemoteAddress = Value1 && ( 255 >= Value3 )
| ( Value2 << 8 ) && ( 255 >= Value4 )) {
| ( Value3 << 16 ) //
| ( Value4 << 24 ); // Build the IPv4 address
RemoteHostAddress.sin_addr.s_addr = (UINT32) RemoteAddress; //
Status = EFI_SUCCESS; pRemoteAddress4->sin_len = sizeof ( *pRemoteAddress4 );
DEBUG (( DEBUG_INFO, pRemoteAddress4->sin_family = AF_INET;
"%d.%d.%d.%d: Remote host IP address\r\n", RemoteAddress = Value1
Value1, | ( Value2 << 8 )
Value2, | ( Value3 << 16 )
Value3, | ( Value4 << 24 );
Value4 )); pRemoteAddress4->sin_addr.s_addr = RemoteAddress;
} Status = EFI_SUCCESS;
}
} //
// Display the IP address
//
DEBUG (( DEBUG_INFO,
"%d.%d.%d.%d: Remote host IP address\r\n",
Value1,
Value2,
Value3,
Value4 ));
} }
if ( EFI_ERROR ( Status )) { else if (( 8 == sscanf ( pRemoteHost,
Print ( L"Invalid digit detected: %d\r\n", *pSeparator ); "%x:%x:%x:%x:%x:%x:%x:%x",
&Value1,
&Value2,
&Value3,
&Value4,
&Value5,
&Value6,
&Value7,
&Value8 ))
&& ( 0xffff >= Value1 )
&& ( 0xffff >= Value2 )
&& ( 0xffff >= Value3 )
&& ( 0xffff >= Value4 )
&& ( 0xffff >= Value5 )
&& ( 0xffff >= Value6 )
&& ( 0xffff >= Value7 )
&& ( 0xffff >= Value8 )) {
//
// Build the IPv6 address
//
pRemoteAddress6->sin6_len = sizeof ( *pRemoteAddress6 );
pRemoteAddress6->sin6_family = AF_INET6;
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ] = (UINT8)( Value1 >> 8 );
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ] = (UINT8)Value1;
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ] = (UINT8)( Value2 >> 8 );
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ] = (UINT8)Value2;
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ] = (UINT8)( Value3 >> 8 );
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ] = (UINT8)Value3;
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ] = (UINT8)( Value4 >> 8 );
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ] = (UINT8)Value4;
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ] = (UINT8)( Value5 >> 8 );
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ] = (UINT8)Value5;
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ] = (UINT8)( Value6 >> 8 );
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ] = (UINT8)Value6;
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ] = (UINT8)( Value7 >> 8 );
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ] = (UINT8)Value7;
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ] = (UINT8)( Value8 >> 8 );
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ] = (UINT8)Value8;
Status = EFI_SUCCESS;
//
// Display the IP address
//
DEBUG (( DEBUG_INFO,
"[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]: Remote host IP address\r\n",
Value1,
Value2,
Value3,
Value4,
Value5,
Value6,
Value7,
Value8 ));
}
else {
Print ( L"ERROR - Invalid IP address!\r\n" );
} }
// //
@ -290,19 +370,43 @@ SocketConnect (
) )
{ {
int ConnectStatus; int ConnectStatus;
UINT32 RemoteAddress; struct sockaddr_in * pRemoteAddress4;
struct sockaddr_in6 * pRemoteAddress6;
EFI_STATUS Status; EFI_STATUS Status;
// //
// Display the connecting message // Display the connecting message
// //
RemoteAddress = RemoteHostAddress.sin_addr.s_addr; pRemoteAddress4 = (struct sockaddr_in *)&RemoteHostAddress;
Print ( L"Connecting to remote system %d.%d.%d.%d:%d\r\n", pRemoteAddress6 = &RemoteHostAddress;
RemoteAddress & 0xff, if ( AF_INET == pRemoteAddress6->sin6_family ) {
( RemoteAddress >> 8 ) & 0xff, Print ( L"Connecting to remote system %d.%d.%d.%d:%d\r\n",
( RemoteAddress >> 16 ) & 0xff, pRemoteAddress4->sin_addr.s_addr & 0xff,
( RemoteAddress >> 24 ) & 0xff, ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,
htons ( RemoteHostAddress.sin_port )); ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,
( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,
htons ( pRemoteAddress4->sin_port ));
}
else {
Print ( L"Connecting to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
htons ( pRemoteAddress6->sin6_port ));
}
// //
// Connect to the remote system // Connect to the remote system
@ -327,15 +431,37 @@ SocketConnect (
// Connect to the remote system // Connect to the remote system
// //
ConnectStatus = connect ( Socket, ConnectStatus = connect ( Socket,
(struct sockaddr *) &RemoteHostAddress, (struct sockaddr *)pRemoteAddress6,
RemoteHostAddress.sin_len ); pRemoteAddress6->sin6_len );
if ( -1 != ConnectStatus ) { if ( -1 != ConnectStatus ) {
Print ( L"Connected to remote system %d.%d.%d.%d:%d\r\n", if ( AF_INET == pRemoteAddress6->sin6_family ) {
RemoteAddress & 0xff, Print ( L"Connected to remote system %d.%d.%d.%d:%d\r\n",
( RemoteAddress >> 8 ) & 0xff, pRemoteAddress4->sin_addr.s_addr & 0xff,
( RemoteAddress >> 16 ) & 0xff, ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,
( RemoteAddress >> 24 ) & 0xff, ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,
htons ( RemoteHostAddress.sin_port )); ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,
htons ( pRemoteAddress4->sin_port ));
}
else {
Print ( L"Connected to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],
pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],
htons ( pRemoteAddress6->sin6_port ));
}
} }
else { else {
// //
@ -358,11 +484,14 @@ SocketConnect (
/** /**
Create the socket Create the socket
@param [in] Family Network family, AF_INET or AF_INET6
@retval EFI_SUCCESS The application is running normally @retval EFI_SUCCESS The application is running normally
@retval Other The user stopped the application @retval Other The user stopped the application
**/ **/
EFI_STATUS EFI_STATUS
SocketNew ( SocketNew (
sa_family_t Family
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -384,7 +513,7 @@ SocketNew (
// //
// Attempt to create the socket // Attempt to create the socket
// //
Socket = socket ( AF_INET, Socket = socket ( Family,
SOCK_STREAM, SOCK_STREAM,
IPPROTO_TCP ); IPPROTO_TCP );
if ( -1 != Socket ) { if ( -1 != Socket ) {
@ -419,7 +548,7 @@ SocketSend (
// //
// Restart the timer // Restart the timer
// //
TimerStart ( 1000 << DATA_RATE_UPDATE_SHIFT ); TimerStart ( 1 * 1000 );
// //
// Loop until the connection breaks or the user stops // Loop until the connection breaks or the user stops
@ -497,7 +626,7 @@ SocketOpen (
// //
// Wait for the network layer to initialize // Wait for the network layer to initialize
// //
Status = SocketNew ( ); Status = SocketNew ( RemoteHostAddress.sin6_family );
if ( EFI_ERROR ( Status )) { if ( EFI_ERROR ( Status )) {
break; break;
} }
@ -584,13 +713,13 @@ Tcp4Close (
// //
// Display the port closed message // Display the port closed message
// //
pIpAddress = (UINT8 *)&RemoteHostAddress.sin_addr.s_addr; pIpAddress = (UINT8 *)&((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;
Print ( L"Closed connection to %d.%d.%d.%d:%d\r\n", Print ( L"Closed connection to %d.%d.%d.%d:%d\r\n",
pIpAddress[0], pIpAddress[0],
pIpAddress[1], pIpAddress[1],
pIpAddress[2], pIpAddress[2],
pIpAddress[3], pIpAddress[3],
htons ( RemoteHostAddress.sin_port )); htons ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));
} }
} }
} }
@ -786,13 +915,13 @@ Tcp4Locate (
// Display the connecting message // Display the connecting message
// //
if ( bTcp4Connecting ) { if ( bTcp4Connecting ) {
pIpAddress = (UINT8 *)&RemoteHostAddress.sin_addr.s_addr; pIpAddress = (UINT8 *)&((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;
Print ( L"Connecting to %d.%d.%d.%d:%d\r\n", Print ( L"Connecting to %d.%d.%d.%d:%d\r\n",
pIpAddress[0], pIpAddress[0],
pIpAddress[1], pIpAddress[1],
pIpAddress[2], pIpAddress[2],
pIpAddress[3], pIpAddress[3],
htons ( RemoteHostAddress.sin_port )); htons ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));
bTcp4Connecting = FALSE; bTcp4Connecting = FALSE;
} }
@ -885,7 +1014,7 @@ Tcp4Send (
// //
// Restart the timer // Restart the timer
// //
TimerStart ( 1000 << DATA_RATE_UPDATE_SHIFT ); TimerStart ( 1 * 1000 );
// //
// Initialize the packet // Initialize the packet
@ -1095,11 +1224,11 @@ Tcp4Open (
Tcp4ConfigData.AccessPoint.StationAddress.Addr[2] = 0; Tcp4ConfigData.AccessPoint.StationAddress.Addr[2] = 0;
Tcp4ConfigData.AccessPoint.StationAddress.Addr[3] = 0; Tcp4ConfigData.AccessPoint.StationAddress.Addr[3] = 0;
Tcp4ConfigData.AccessPoint.StationPort = 0; Tcp4ConfigData.AccessPoint.StationPort = 0;
Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[0] = (UINT8) RemoteHostAddress.sin_addr.s_addr; Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[0] = (UINT8) ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;
Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[1] = (UINT8)( RemoteHostAddress.sin_addr.s_addr >> 8 ); Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[1] = (UINT8)( ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr >> 8 );
Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[2] = (UINT8)( RemoteHostAddress.sin_addr.s_addr >> 16 ); Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[2] = (UINT8)( ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr >> 16 );
Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[3] = (UINT8)( RemoteHostAddress.sin_addr.s_addr >> 24 ); Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[3] = (UINT8)( ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr >> 24 );
Tcp4ConfigData.AccessPoint.RemotePort = RemoteHostAddress.sin_port; Tcp4ConfigData.AccessPoint.RemotePort = ((struct sockaddr_in *)&RemoteHostAddress)->sin_port;
Tcp4ConfigData.AccessPoint.UseDefaultAddress = TRUE; Tcp4ConfigData.AccessPoint.UseDefaultAddress = TRUE;
Tcp4ConfigData.AccessPoint.SubnetMask.Addr[0] = 0; Tcp4ConfigData.AccessPoint.SubnetMask.Addr[0] = 0;
Tcp4ConfigData.AccessPoint.SubnetMask.Addr[1] = 0; Tcp4ConfigData.AccessPoint.SubnetMask.Addr[1] = 0;
@ -1152,13 +1281,13 @@ Tcp4Open (
// //
// Display the connection // Display the connection
// //
pIpAddress = (UINT8 *)&RemoteHostAddress.sin_addr.s_addr; pIpAddress = (UINT8 *)&((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;
Print ( L"Connected to %d.%d.%d.%d:%d\r\n", Print ( L"Connected to %d.%d.%d.%d:%d\r\n",
pIpAddress[0], pIpAddress[0],
pIpAddress[1], pIpAddress[1],
pIpAddress[2], pIpAddress[2],
pIpAddress[3], pIpAddress[3],
htons ( RemoteHostAddress.sin_port )); htons ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));
} while ( 0 ); } while ( 0 );
if ( EFI_ERROR ( Status )) { if ( EFI_ERROR ( Status )) {
@ -1193,10 +1322,10 @@ TimerCallback (
IN VOID * pContext IN VOID * pContext
) )
{ {
UINT64 BytesSent; UINT32 Average;
UINT64 DeltaBytes; UINT64 BitsPerSecond;
UINT32 Delta; UINT32 Index;
UINT64 Average; UINT64 TotalBytes;
// //
// Notify the other code of the timer tick // Notify the other code of the timer tick
@ -1206,65 +1335,82 @@ TimerCallback (
// //
// Update the average bytes per second // Update the average bytes per second
// //
BytesSent = TotalBytesSent; if ( 0 != TotalBytesSent ) {
if ( 0 != BytesSent ) { BytesSent[ In ] = TotalBytesSent;
DeltaBytes = AverageBytes >> AVERAGE_SHIFT_COUNT; TotalBytesSent = 0;
AverageBytes -= DeltaBytes; In += 1;
DeltaBytes = BytesSent - PreviousBytes; if ( DATA_SAMPLES <= In ) {
PreviousBytes = BytesSent; In = 0;
AverageBytes += DeltaBytes; }
// //
// Separate the samples // Separate the samples
// //
if (( 2 << AVERAGE_SHIFT_COUNT ) == Samples ) { if ( DATA_SAMPLES == Samples ) {
Print ( L"---------- Stable average ----------\r\n" ); Print ( L"---------- Stable average ----------\r\n" );
} }
Samples += 1; Samples += 1;
//
// Compute the data rate
//
TotalBytes = 0;
for ( Index = 0; DATA_SAMPLES > Index; Index++ ) {
TotalBytes += BytesSent[ Index ];
}
Average = (UINT32)RShiftU64 ( TotalBytes, DATA_SAMPLE_SHIFT );
BitsPerSecond = Average * 8;
// //
// Display the data rate // Display the data rate
// //
Delta = (UINT32)( DeltaBytes >> DATA_RATE_UPDATE_SHIFT ); if (( RANGE_SWITCH >> 10 ) > Average ) {
Average = AverageBytes >> ( AVERAGE_SHIFT_COUNT + DATA_RATE_UPDATE_SHIFT ); Print ( L"Ave: %d Bytes/Sec, %Ld Bits/sec\r\n",
if ( Average < RANGE_SWITCH ) { Average,
Print ( L"%d Bytes/sec, Ave: %d Bytes/Sec\r\n", BitsPerSecond );
Delta,
(UINT32) Average );
} }
else { else {
Average >>= 10; BitsPerSecond /= 1000;
if ( Average < RANGE_SWITCH ) { if ( RANGE_SWITCH > Average ) {
Print ( L"%d Bytes/sec, Ave: %d KiBytes/Sec\r\n", Print ( L"Ave: %d.%03d KiBytes/Sec, %Ld KBits/sec\r\n",
Delta, Average >> 10,
(UINT32) Average ); (( Average & 0x3ff ) * 1000 ) >> 10,
BitsPerSecond );
} }
else { else {
BitsPerSecond /= 1000;
Average >>= 10; Average >>= 10;
if ( Average < RANGE_SWITCH ) { if ( RANGE_SWITCH > Average ) {
Print ( L"%d Bytes/sec, Ave: %d MiBytes/Sec\r\n", Print ( L"Ave: %d.%03d MiBytes/Sec, %Ld MBits/sec\r\n",
Delta, Average >> 10,
(UINT32) Average ); (( Average & 0x3ff ) * 1000 ) >> 10,
BitsPerSecond );
} }
else { else {
BitsPerSecond /= 1000;
Average >>= 10; Average >>= 10;
if ( Average < RANGE_SWITCH ) { if ( RANGE_SWITCH > Average ) {
Print ( L"%d Bytes/sec, Ave: %d GiBytes/Sec\r\n", Print ( L"Ave: %d.%03d GiBytes/Sec, %Ld GBits/sec\r\n",
Delta, Average >> 10,
(UINT32) Average ); (( Average & 0x3ff ) * 1000 ) >> 10,
BitsPerSecond );
} }
else { else {
BitsPerSecond /= 1000;
Average >>= 10; Average >>= 10;
if ( Average < RANGE_SWITCH ) { if ( RANGE_SWITCH > Average ) {
Print ( L"%d Bytes/sec, Ave: %d TiBytes/Sec\r\n", Print ( L"Ave: %d.%03d TiBytes/Sec, %Ld TBits/sec\r\n",
Delta, Average >> 10,
Average ); (( Average & 0x3ff ) * 1000 ) >> 10,
BitsPerSecond );
} }
else { else {
BitsPerSecond /= 1000;
Average >>= 10; Average >>= 10;
Print ( L"%d Bytes/sec, Ave: %d PiBytes/Sec\r\n", Print ( L"Ave: %d.%03d PiBytes/Sec, %Ld PBits/sec\r\n",
Delta, Average >> 10,
(UINT32) Average ); (( Average & 0x3ff ) * 1000 ) >> 10,
BitsPerSecond );
} }
} }
} }
@ -1528,17 +1674,8 @@ main (
// No bytes sent so far // No bytes sent so far
// //
TotalBytesSent = 0; TotalBytesSent = 0;
AverageBytes = 0;
PreviousBytes = 0;
Samples = 0; Samples = 0;
memset ( &BytesSent, 0, sizeof ( BytesSent ));
//
// Get the port number
//
ZeroMem ( &RemoteHostAddress, sizeof ( RemoteHostAddress ));
RemoteHostAddress.sin_len = sizeof ( RemoteHostAddress );
RemoteHostAddress.sin_family = AF_INET;
RemoteHostAddress.sin_port = htons ( PcdGet16 ( DataSource_Port ));
// //
// Get the IP address // Get the IP address

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such
@ -39,10 +39,11 @@
[Pcd] [Pcd]
gStdLibTokenSpaceGuid.DataSource_Port gAppPkgTokenSpaceGuid.DataSource_Port
[Packages] [Packages]
AppPkg/AppPkg.dec
MdePkg/MdePkg.dec MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec ShellPkg/ShellPkg.dec
StdLib/StdLib.dec StdLib/StdLib.dec

View File

@ -0,0 +1,120 @@
/** @file
Test the getaddrinfo API
Copyright (c) 2011, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <Uefi.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
char mBuffer[65536];
/**
Test the getaddrinfo API
@param [in] Argc The number of arguments
@param [in] Argv The argument value array
@retval 0 The application exited normally.
@retval Other An error occurred.
**/
int
main (
IN int Argc,
IN char **Argv
)
{
int AppStatus;
int Index;
int MaxLen;
struct addrinfo * pAddrInfo;
char * pHostName;
struct addrinfo * pInfo;
char * pServerName;
//
// Determine if the host name is specified
//
AppStatus = 0;
if ( 1 == Argc ) {
printf ( "%s <host name> <server name>\r\n", Argv[0]);
}
else {
//
// Translate the host name
//
pHostName = Argv[1];
pServerName = NULL;
if ( 2 < Argc ) {
pServerName = Argv[2];
}
AppStatus = getaddrinfo ( pHostName,
pServerName,
NULL,
&pAddrInfo );
if ( 0 != AppStatus ) {
printf ( "ERROR - address info not found, errno: %d\r\n", AppStatus );
}
if ( NULL == pAddrInfo ) {
printf ( "ERROR - No address info structure allocated\r\n" );
}
else {
//
// Walk the list of addresses
//
pInfo = pAddrInfo;
while ( NULL != pInfo ) {
//
// Display this entry
//
printf ( "0x%08x: ai_flags\r\n", pInfo->ai_flags );
printf ( "0x%08x: ai_family\r\n", pInfo->ai_family );
printf ( "0x%08x: ai_socktype\r\n", pInfo->ai_socktype );
printf ( "0x%08x: ai_protocol\r\n", pInfo->ai_protocol );
printf ( "0x%08x: ai_addrlen\r\n", pInfo->ai_addrlen );
printf ( "%s: ai_canonname\r\n", pInfo->ai_canonname );
printf ( " 0x%02x: ai_addr->sa_len\r\n", (UINT8)pInfo->ai_addr->sa_len );
printf ( " 0x%02x: ai_addr->sa_family\r\n", (UINT8)pInfo->ai_addr->sa_family );
MaxLen = pInfo->ai_addr->sa_len;
if ( sizeof ( struct sockaddr_in6 ) < MaxLen ) {
MaxLen = sizeof ( struct sockaddr_in6 );
}
for ( Index = 0; ( MaxLen - 2 ) > Index; Index++ ) {
printf ( " 0x%02x: ai_addr->sa_data[%02d]\r\n", (UINT8)pInfo->ai_addr->sa_data [ Index ], Index );
}
//
// Set the next entry
//
pInfo = pInfo->ai_next;
}
//
// Done with this structures
//
freeaddrinfo ( pAddrInfo );
}
}
//
// All done
//
return AppStatus;
}

View File

@ -0,0 +1,63 @@
#/** @file
# GetAddrInfo Application
#
# This file contains an 'Intel Peripheral Driver' 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.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = GetAddrInfo
FILE_GUID = 4C26DF71-EBE7-4dea-B5E2-0B5980433908
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = ShellCEntryLib
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
GetAddrInfo.c
[Packages]
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec
StdLib/StdLib.dec
[LibraryClasses]
BaseMemoryLib
BsdSocketLib
DevShell
EfiSocketLib
LibC
LibMath
LibNetUtil
ShellCEntryLib
UefiBootServicesTableLib
# UseSocketDxe
[BuildOptions]
INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
MSFT:*_*_*_CC_FLAGS = /Od
GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such

View File

@ -0,0 +1,120 @@
/** @file
Test the getnameinfo API
Copyright (c) 2011, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <Uefi.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
char mBuffer[65536];
char mHostName[256];
char mServiceName[256];
/**
Test the getnameinfo API
@param [in] Argc The number of arguments
@param [in] Argv The argument value array
@retval 0 The application exited normally.
@retval Other An error occurred.
**/
int
main (
IN int Argc,
IN char **Argv
)
{
int AppStatus;
struct addrinfo * pAddrInfo;
char * pHostName;
struct addrinfo * pInfo;
char * pServerName;
//
// Determine if the host name is specified
//
AppStatus = 0;
if ( 1 == Argc ) {
printf ( "%s <host address> <server name>\r\n", Argv[0]);
}
else {
//
// Translate the host name
//
pHostName = Argv[1];
pServerName = NULL;
if ( 2 < Argc ) {
pServerName = Argv[2];
}
AppStatus = getaddrinfo ( pHostName,
pServerName,
NULL,
&pAddrInfo );
if ( 0 != AppStatus ) {
printf ( "ERROR - address info not found, errno: %d\r\n", AppStatus );
}
if ( NULL == pAddrInfo ) {
printf ( "ERROR - No address info structure allocated\r\n" );
}
else {
//
// Walk the list of names
//
pInfo = pAddrInfo;
while ( NULL != pInfo ) {
//
// Get the name info
//
AppStatus = getnameinfo ((struct sockaddr *)pInfo->ai_addr,
pInfo->ai_addrlen,
&mHostName[0],
sizeof ( mHostName ),
&mServiceName[0],
sizeof ( mServiceName ),
0 );
if ( 0 != AppStatus ) {
break;
}
//
// Display this entry
//
printf ( "%s: HostName\r\n", mHostName[0]);
printf ( "%s: Service Name\r\n", &mServiceName[0]);
//
// Set the next entry
//
pInfo = pInfo->ai_next;
}
//
// Done with this structures
//
freeaddrinfo ( pAddrInfo );
}
}
//
// All done
//
return AppStatus;
}

View File

@ -0,0 +1,63 @@
#/** @file
# GetNameInfo Application
#
# This file contains an 'Intel Peripheral Driver' 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.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = GetNameInfo
FILE_GUID = 553087F6-BAAC-4d7f-97B4-31D8179AAE15
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = ShellCEntryLib
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
GetNameInfo.c
[Packages]
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec
StdLib/StdLib.dec
[LibraryClasses]
BaseMemoryLib
BsdSocketLib
DevShell
EfiSocketLib
LibC
LibMath
LibNetUtil
ShellCEntryLib
UefiBootServicesTableLib
# UseSocketDxe
[BuildOptions]
INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
MSFT:*_*_*_CC_FLAGS = /Od
GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such

View File

@ -6,9 +6,11 @@
[Components] [Components]
AppPkg/Applications/Sockets/DataSink/DataSink.inf AppPkg/Applications/Sockets/DataSink/DataSink.inf
AppPkg/Applications/Sockets/DataSource/DataSource.inf AppPkg/Applications/Sockets/DataSource/DataSource.inf
AppPkg/Applications/Sockets/GetAddrInfo/GetAddrInfo.inf
AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.inf AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.inf
AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.inf AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.inf
AppPkg/Applications/Sockets/GetHostByName/GetHostByName.inf AppPkg/Applications/Sockets/GetHostByName/GetHostByName.inf
AppPkg/Applications/Sockets/GetNameInfo/GetNameInfo.inf
AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.inf AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.inf
AppPkg/Applications/Sockets/GetNetByName/GetNetByName.inf AppPkg/Applications/Sockets/GetNetByName/GetNetByName.inf
AppPkg/Applications/Sockets/GetServByName/GetServByName.inf AppPkg/Applications/Sockets/GetServByName/GetServByName.inf

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/** @file /** @file
Definitions for the TFTP server. Definitions for the TFTP server.
Copyright (c) 2011, Intel Corporation Copyright (c) 2011, 2012, Intel Corporation
All rights reserved. This program and the accompanying materials All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -16,6 +16,7 @@
#define _TFTP_SERVER_H_ #define _TFTP_SERVER_H_
#include <errno.h> #include <errno.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <Uefi.h> #include <Uefi.h>
@ -24,29 +25,33 @@
#include <Library/BaseMemoryLib.h> #include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h> #include <Library/PcdLib.h>
#include <Library/TimerLib.h>
#include <Library/UefiApplicationEntryPoint.h> #include <Library/UefiApplicationEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h> #include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h> #include <Library/UefiLib.h>
#include <Protocol/BlockIo.h> #include <Protocol/BlockIo.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet6/in6.h>
#include <sys/EfiSysCall.h> #include <sys/EfiSysCall.h>
#include <sys/poll.h> #include <sys/poll.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/Stat.h>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Macros // Macros
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */ #if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
#define DBG_ENTER() DEBUG (( DEBUG_INFO, "Entering " __FUNCTION__ "\n" )) ///< Display routine entry #define DBG_ENTER() DEBUG (( DEBUG_ENTER_EXIT, "Entering " __FUNCTION__ "\n" )) ///< Display routine entry
#define DBG_EXIT() DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ "\n" )) ///< Display routine exit #define DBG_EXIT() DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ "\n" )) ///< Display routine exit
#define DBG_EXIT_DEC(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %d\n", Status )) ///< Display routine exit with decimal value #define DBG_EXIT_DEC(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: %d\n", Status )) ///< Display routine exit with decimal value
#define DBG_EXIT_HEX(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status )) ///< Display routine exit with hex value #define DBG_EXIT_HEX(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status )) ///< Display routine exit with hex value
#define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %r\n", Status )) ///< Display routine exit with status value #define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: %r\n", Status )) ///< Display routine exit with status value
#define DBG_EXIT_TF(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" )) ///< Display routine with TRUE/FALSE value #define DBG_EXIT_TF(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" )) ///< Display routine with TRUE/FALSE value
#else // _MSC_VER #else // _MSC_VER
#define DBG_ENTER() #define DBG_ENTER()
#define DBG_EXIT() #define DBG_EXIT()
@ -62,14 +67,22 @@
// Constants // Constants
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#define DEBUG_PORT_WORK 0x40000000 ///< Display the port work messages #define ACK_SHIFT 4 ///< Number of samples in ACK average
#define DEBUG_SERVER_TIMER 0x20000000 ///< Display the socket poll messages
#define DEBUG_TFTP_PORT 0x10000000 ///< Display the TFTP port messages #define DEBUG_WINDOW 0x00000001 ///< Display the window messages
#define DEBUG_TFTP_REQUEST 0x08000000 ///< Display the TFTP request messages #define DEBUG_TX_PACKET 0x00000002 ///< Display the transmit packet messages
#define DEBUG_TX 0x04000000 ///< Display transmit messages #define DEBUG_FILE_BUFFER 0x00000004 ///< Display the file buffer messages
#define DEBUG_SOCKET_POLL 0x02000000 ///< Display the socket poll messages #define DEBUG_SERVER_TIMER 0x00000008 ///< Display the socket poll messages
#define DEBUG_RX 0x01000000 ///< Display receive messages #define DEBUG_TFTP_REQUEST 0x00000010 ///< Display the TFTP request messages
#define DEBUG_TFTP_ACK 0x00800000 ///< Display the TFTP ACK messages #define DEBUG_PORT_WORK 0x00000020 ///< Display the port work messages
#define DEBUG_SOCKET_POLL 0x00000040 ///< Display the socket poll messages
#define DEBUG_TFTP_PORT 0x00000080 ///< Display the TFTP port messages
#define DEBUG_TX 0x00000100 ///< Display transmit messages
#define DEBUG_RX 0x00000200 ///< Display receive messages
#define DEBUG_TFTP_ACK 0x00000400 ///< Display the TFTP ACK messages
#define DEBUG_ENTER_EXIT 0x00000800 ///< Display entry and exit messages
#define MAX_PACKETS 8 ///< Maximum number of packets in the window
#define TFTP_PORT_POLL_DELAY ( 2 * 1000 ) ///< Delay in milliseconds for attempts to open the TFTP port #define TFTP_PORT_POLL_DELAY ( 2 * 1000 ) ///< Delay in milliseconds for attempts to open the TFTP port
#define CLIENT_POLL_DELAY 50 ///< Delay in milliseconds between client polls #define CLIENT_POLL_DELAY 50 ///< Delay in milliseconds between client polls
@ -123,10 +136,32 @@
#define TFTP_MAX_BLOCK_SIZE 4096 ///< Maximum block size #define TFTP_MAX_BLOCK_SIZE 4096 ///< Maximum block size
#define TFTP_ERROR_SEE_MSG 0 ///< See the error message
#define TFTP_ERROR_NOT_FOUND 1 ///< File not found
#define TFTP_ERROR_ACCESS_VIOLATION 2 ///< Access violation
#define TFTP_ERROR_DISK_FULL 3 ///< Disk full
#define TFTP_ERROR_ILLEGAL_OP 4 ///< Illegal operation
#define TFTP_ERROR_UNKNOWN_XFER_ID 5 ///< Unknown transfer ID
#define TFTP_ERROR_FILE_EXISTS 6 ///< File already exists
#define TFTP_ERROR_NO_SUCH_USER 7 ///< No such user
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Data Types // Data Types
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/**
Packet structure
**/
typedef struct _TFTP_PACKET TFTP_PACKET;
typedef struct _TFTP_PACKET {
TFTP_PACKET * pNext; ///< Next packet in list
UINT64 TxTime; ///< Time the transmit was performed
ssize_t TxBytes; ///< Bytes in the TX buffer
UINT32 RetryCount; ///< Number of transmissions
UINT16 BlockNumber; ///< Block number of this packet
UINT8 TxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Transmit buffer
} GCC_TFTP_PACKET;
/** /**
Port control structure Port control structure
**/ **/
@ -135,33 +170,49 @@ typedef struct _TSDT_CONNECTION_CONTEXT {
// //
// Remote connection management // Remote connection management
// //
TSDT_CONNECTION_CONTEXT * pNext; ///< Next context in the connection list TSDT_CONNECTION_CONTEXT * pNext; ///< Next context in the connection list
struct sockaddr_in RemoteAddress; ///< Remote address struct sockaddr_in6 RemoteAddress; ///< Remote address
int SocketFd; ///< Socket file descriptor
//
// TFTP management parameters
//
UINT16 AckNext; ///< Next block to be received
BOOLEAN bExpectAck; ///< TRUE for read, FALSE for write
UINT32 BlockSize; ///< Negotiated block size
UINT32 Timeout; ///< Number of seconds to wait before retransmission
// //
// File management parameters // File management parameters
// //
EFI_HANDLE File; ///< NULL while file is closed FILE * File; ///< NULL while file is closed
UINT64 LengthInBytes; ///< Size of the file UINT64 LengthInBytes; ///< Size of the file
UINT64 MaxTransferSize; ///< Maximum transfer size UINT64 BytesRemaining; ///< Number of bytes remaining to be sent
UINT64 BytesToSend; ///< Number of bytes to send
UINT64 ValidBytes; ///< Number of valid bytes in the buffer
BOOLEAN bEofSent; ///< End of file sent BOOLEAN bEofSent; ///< End of file sent
UINT8 * pFill; ///< Next portion of the buffer to fill
UINT8 * pBuffer; ///< Pointer into the file data UINT8 * pBuffer; ///< Pointer into the file data
UINT8 * pEnd; ///< End of the file data UINT8 * pEnd; ///< End of the file data
UINT8 FileData[ 64 * TFTP_MAX_BLOCK_SIZE ]; ///< File data to send UINT8 FileData[ 2 * MAX_PACKETS * TFTP_MAX_BLOCK_SIZE ]; ///< File data to send
UINT64 TimeStart; ///< Start of file transfer
//
// TFTP management parameters
//
UINT16 BlockNumber; ///< Next block to be transmitted
UINT32 BlockSize; ///< Negotiated block size
//
// Window management
//
UINT32 AckCount; ///< Number of ACKs to receive before increasing the window
UINT32 PacketsInWindow; ///< Number of packets in the window
UINT32 Threshold; ///< Size of window when ACK count becomes logrithmic
UINT32 WindowSize; ///< Size of the transmit window
UINT64 MaxTimeout; ///< Maximum number of seconds to wait before retransmission
UINT64 Rtt2x; ///< Twice the average round trip time in nanoseconds
// //
// Buffer management // Buffer management
// //
ssize_t TxBytes; ///< Bytes in the TX buffer TFTP_PACKET * pFreeList; ///< List of free packets
UINT8 TxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Transmit buffer TFTP_PACKET * pTxHead; ///< First packet in the list of packets for transmission
TFTP_PACKET * pTxTail; ///< Last packet in the list of packets for transmission
TFTP_PACKET ErrorPacket; ///< Error packet
TFTP_PACKET Tx[ MAX_PACKETS ];///< Transmit packets
}GCC_TSDT_CONNECTION_CONTEXT; }GCC_TSDT_CONNECTION_CONTEXT;
/** /**
@ -175,20 +226,32 @@ typedef struct {
// //
EFI_HANDLE ImageHandle; ///< Image handle EFI_HANDLE ImageHandle; ///< Image handle
//
// Performance management
//
UINT64 ClockFrequency; ///< Frequency of the clock
UINT64 Time1; ///< Clock value after rollover
UINT64 Time2; ///< Clock value before rollover
UINT64 RxTime; ///< Time when the packet was recevied
// //
// TFTP port management // TFTP port management
// //
BOOLEAN bTimerRunning; ///< Port creation timer status
EFI_EVENT TimerEvent; ///< Timer to open TFTP port EFI_EVENT TimerEvent; ///< Timer to open TFTP port
struct pollfd TftpPort; ///< Poll descriptor for the TFTP port int Udpv4Index; ///< Entry for UDPv4
struct sockaddr_in TftpServerAddress; ///< Address of the local TFTP server int Udpv6Index; ///< Entry for UDPv6
int Entries; ///< Number of TFTP ports
struct pollfd TftpPort [ 2 ]; ///< Poll descriptor for the TFTP ports (UDP4, UDP6)
// //
// Request management // Request management
// //
struct sockaddr_in RemoteAddress; ///< Remote address union {
ssize_t RxBytes; ///< Receive data length in bytes struct sockaddr_in v4; ///< UDP4 address
UINT8 RxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Receive buffer struct sockaddr_in6 v6; ///< UDP6 address
} RemoteAddress; ///< Remote address
ssize_t RxBytes; ///< Receive data length in bytes
UINT8 RxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Receive buffer
// //
// Client port management // Client port management
@ -204,6 +267,92 @@ extern TSDT_TFTP_SERVER mTftpServer;
// Support routines // Support routines
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/**
Queue data packets for transmission
@param [in] pContext Connection context structure address
@retval TRUE if a read error occurred
**/
BOOLEAN
PacketFill (
IN TSDT_CONNECTION_CONTEXT * pContext
);
/**
Free the packet
@param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
@param [in] pPacket Address of a ::TFTP_PACKET structure
**/
VOID
PacketFree(
IN TSDT_CONNECTION_CONTEXT * pContext,
IN TFTP_PACKET * pPacket
);
/**
Get a packet for transmission
@param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
@retval Address of a ::TFTP_PACKET structure
**/
TFTP_PACKET *
PacketGet (
IN TSDT_CONNECTION_CONTEXT * pContext
);
/**
Queue the packet for transmission
@param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
@param [in] pPacket Address of a ::TFTP_PACKET structure
@retval TRUE if a transmission error has occurred
**/
BOOLEAN
PacketQueue (
IN TSDT_CONNECTION_CONTEXT * pContext,
IN TFTP_PACKET * pPacket
);
/**
Transmit the packet
@param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
@param [in] pPacket Address of a ::TFTP_PACKET structure
@retval EFI_SUCCESS Message processed successfully
**/
EFI_STATUS
PacketTx (
IN TSDT_CONNECTION_CONTEXT * pContext,
IN TFTP_PACKET * pPacket
);
/**
Build and send an error packet
@param [in] pContext The context structure address.
@param [in] Error Error number for the packet
@param [in] pError Zero terminated error string address
@retval EFI_SUCCESS Message processed successfully
**/
EFI_STATUS
SendError (
IN TSDT_CONNECTION_CONTEXT * pContext,
IN UINT16 Error,
IN UINT8 * pError
);
/** /**
Process the TFTP request Process the TFTP request
@ -224,105 +373,56 @@ TftpOptionValue (
@param [in] pTftpServer The TFTP server control structure address. @param [in] pTftpServer The TFTP server control structure address.
@param [in] pContext Connection context structure address @param [in] pContext Connection context structure address
@param [in] SocketFd Socket file descriptor
**/ **/
VOID VOID
TftpProcessRequest ( TftpProcessRequest (
IN TSDT_TFTP_SERVER * pTftpServer, IN TSDT_TFTP_SERVER * pTftpServer,
IN TSDT_CONNECTION_CONTEXT * pContext IN TSDT_CONNECTION_CONTEXT * pContext,
IN int SocketFd
); );
/** /**
Build and send an error packet Process the read request
@param [in] pTftpServer The TFTP server control structure address. @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
@param [in] pContext The context structure address. @param [in] pContext Connection context structure address
@param [in] Error Error number for the packet @param [in] SocketFd Socket file descriptor
@param [in] pError Zero terminated error string address
@retval EFI_SUCCESS Message processed successfully @retval TRUE if the context should be closed
**/ **/
EFI_STATUS BOOLEAN
TftpSendError ( TftpRead (
IN TSDT_TFTP_SERVER * pTftpServer, IN TSDT_TFTP_SERVER * pTftpServer,
IN TSDT_CONNECTION_CONTEXT * pContext, IN TSDT_CONNECTION_CONTEXT * pContext,
IN UINT16 Error, IN int SocketFd
IN UINT8 * pError
); );
/** /**
Send the next block of file system data Update the window due to the ACK
@param [in] pTftpServer The TFTP server control structure address. @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
@param [in] pContext The context structure address. @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
@param [in] pPacket Address of a ::TFTP_PACKET structure
@retval EFI_SUCCESS Message processed successfully
**/
EFI_STATUS
TftpSendNextBlock (
IN TSDT_TFTP_SERVER * pTftpServer,
IN TSDT_CONNECTION_CONTEXT * pContext
);
/**
TFTP port creation timer routine
This routine polls the socket layer waiting for the initial network connection
which will enable the creation of the TFTP port. The socket layer will manage
the coming and going of the network connections after that until the last network
connection is broken.
@param [in] pTftpServer The TFTP server control structure address.
**/ **/
VOID VOID
TftpServerTimer ( WindowAck (
IN TSDT_TFTP_SERVER * pTftpServer
);
/**
Start the TFTP server port creation timer
@param [in] pTftpServer The TFTP 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
TftpServerTimerStart (
IN TSDT_TFTP_SERVER * pTftpServer
);
/**
Stop the TFTP server port creation timer
@param [in] pTftpServer The TFTP server control structure address.
@retval EFI_SUCCESS The TFTP port timer is stopped
@retval Other Failed to stop the TFTP port timer
**/
EFI_STATUS
TftpServerTimerStop (
IN TSDT_TFTP_SERVER * pTftpServer
);
/**
Send the next TFTP packet
@param [in] pTftpServer The TFTP server control structure address.
@param [in] pContext The context structure address.
@retval EFI_SUCCESS Message processed successfully
**/
EFI_STATUS
TftpTxPacket (
IN TSDT_TFTP_SERVER * pTftpServer, IN TSDT_TFTP_SERVER * pTftpServer,
IN TSDT_CONNECTION_CONTEXT * pContext,
IN TFTP_PACKET * pPacket
);
/**
A timeout has occurred, close the window
@param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
**/
VOID
WindowTimeout (
IN TSDT_CONNECTION_CONTEXT * pContext IN TSDT_CONNECTION_CONTEXT * pContext
); );

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such
@ -39,7 +39,17 @@
TftpServer.c TftpServer.c
[Pcd]
gAppPkgTokenSpaceGuid.Tftp_AckLogBase
gAppPkgTokenSpaceGuid.Tftp_AckMultiplier
gAppPkgTokenSpaceGuid.Tftp_Bandwidth
gAppPkgTokenSpaceGuid.Tftp_HighSpeed
gAppPkgTokenSpaceGuid.Tftp_MaxRetry
gAppPkgTokenSpaceGuid.Tftp_MaxTimeoutInSec
[Packages] [Packages]
AppPkg/AppPkg.dec
MdePkg/MdePkg.dec MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec ShellPkg/ShellPkg.dec
StdLib/StdLib.dec StdLib/StdLib.dec
@ -54,6 +64,7 @@
LibC LibC
ShellLib ShellLib
ShellCEntryLib ShellCEntryLib
TimerLib
UefiBootServicesTableLib UefiBootServicesTableLib
UefiLib UefiLib
UefiRuntimeServicesTableLib UefiRuntimeServicesTableLib

View 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;
}

View File

@ -401,8 +401,8 @@ HttpPageTrailer (
int RetVal; int RetVal;
EFI_STATUS Status; EFI_STATUS Status;
socklen_t LengthInBytes; socklen_t LengthInBytes;
struct sockaddr_in LocalAddress; struct sockaddr_in6 LocalAddress;
struct sockaddr_in RemoteAddress; struct sockaddr_in6 RemoteAddress;
DBG_ENTER ( ); DBG_ENTER ( );
@ -413,12 +413,13 @@ HttpPageTrailer (
LengthInBytes = sizeof ( LocalAddress ); LengthInBytes = sizeof ( LocalAddress );
RetVal = getsockname ( SocketFD, (struct sockaddr *)&LocalAddress, &LengthInBytes ); RetVal = getsockname ( SocketFD, (struct sockaddr *)&LocalAddress, &LengthInBytes );
if ( 0 == RetVal ) { if ( 0 == RetVal ) {
LengthInBytes = sizeof ( LocalAddress );
RetVal = getpeername ( SocketFD, (struct sockaddr *)&RemoteAddress, &LengthInBytes ); RetVal = getpeername ( SocketFD, (struct sockaddr *)&RemoteAddress, &LengthInBytes );
if ( 0 == RetVal ) { if ( 0 == RetVal ) {
// //
// Seperate the body from the trailer // 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 )) { if ( EFI_ERROR ( Status )) {
break; break;
} }
@ -438,7 +439,7 @@ HttpPageTrailer (
if ( EFI_ERROR ( Status )) { if ( EFI_ERROR ( Status )) {
break; break;
} }
Status = HttpSendAnsiString ( SocketFD, pPort, "\r\n" ); Status = HttpSendAnsiString ( SocketFD, pPort, "</code>\r\n" );
if ( EFI_ERROR ( Status )) { if ( EFI_ERROR ( Status )) {
break; break;
} }
@ -1213,7 +1214,7 @@ HttpSendHexBits (
// //
Digit = (UINT32)(( Value >> Shift ) & 0xf ); Digit = (UINT32)(( Value >> Shift ) & 0xf );
if ( 10 <= Digit ) { if ( 10 <= Digit ) {
Digit += 'A' - '0' - 10; Digit += 'a' - '0' - 10;
} }
// //
@ -1274,7 +1275,7 @@ HttpSendHexValue (
// //
Digit = (UINT32)(( Value >> Shift ) & 0xf ); Digit = (UINT32)(( Value >> Shift ) & 0xf );
if ( 10 <= Digit ) { 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 Output an IP address to the HTML page
@ -1318,41 +1425,109 @@ EFI_STATUS
HttpSendIpAddress ( HttpSendIpAddress (
IN int SocketFD, IN int SocketFD,
IN WSDT_PORT * pPort, 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; EFI_STATUS Status;
// //
// Output the IPv4 address // Use break instead of goto
// //
Status = HttpSendValue ( SocketFD, pPort, (UINT8)pAddress->sin_addr.s_addr ); for ( ; ; ) {
if ( !EFI_ERROR ( Status )) { //
Status = HttpSendByte ( SocketFD, pPort, '.' ); // Determine the type of address
if ( !EFI_ERROR ( Status )) { //
Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pAddress->sin_addr.s_addr >> 8 )); if ( AF_INET6 == pAddress->sin6_family ) {
if ( !EFI_ERROR ( Status )) { pIpv6 = pAddress;
Status = HttpSendByte ( SocketFD, pPort, '.' );
if ( !EFI_ERROR ( Status )) { //
Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pAddress->sin_addr.s_addr >> 16 )); // Display the address in RFC2732 format
if ( !EFI_ERROR ( Status )) { //
Status = HttpSendByte ( SocketFD, pPort, '.' ); bZeroSuppression = FALSE;
if ( !EFI_ERROR ( Status )) { Status = HttpSendByte ( SocketFD, pPort, '[' );
Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pAddress->sin_addr.s_addr >> 24 )); if ( EFI_ERROR ( Status )) {
if ( !EFI_ERROR ( Status )) { break;
// }
// Output the port number for ( Index = 0; 8 > Index; Index++ ) {
// Status = HttpSendIp6Value ( SocketFD,
Status = HttpSendByte ( SocketFD, pPort, ':' ); pPort,
if ( !EFI_ERROR ( Status )) { pIpv6->sin6_addr.__u6_addr.__u6_addr16[ Index ],
Status = HttpSendValue ( SocketFD, pPort, htons ( pAddress->sin_port )); (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;
} }
// //

View File

@ -44,10 +44,12 @@ CONST DT_PAGE mPageList[] = {
{ L"/DhcpOptions", DhcpOptionsPage, L"DHCP Options" }, ///< Display the DHCP options { L"/DhcpOptions", DhcpOptionsPage, L"DHCP Options" }, ///< Display the DHCP options
{ PAGE_ACPI_DSDT, AcpiDsdtPage, L"DSDT - Differentiated System Description Table" }, ///< Format DSDT { 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 { 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 { PAGE_ACPI_FADT, AcpiFadtPage, L"FADT - Fixed ACPI Description Table" }, ///< Format FADT
{ L"/Firmware", FirmwarePage, L"Firmware" }, ///< Firmware status { L"/Firmware", FirmwarePage, L"Firmware" }, ///< Firmware status
{ L"/Handles", HandlePage, L"Display handles and associated protocol GUIDs" }, ///< Handle database page { L"/Handles", HandlePage, L"Display handles and associated protocol GUIDs" }, ///< Handle database page
{ L"/Hello", HelloPage, L"Hello World" }, ///< Hello world 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 { 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_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 { PAGE_ACPI_RSDP_30, AcpiRsdp30Page, L"RSDP 3.0 - ACPI Root System Description Pointer" }, ///< Format RSDP 3.0 table

View 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;
}

View File

@ -337,7 +337,7 @@ PortWork (
size_t LengthInBytes; size_t LengthInBytes;
int NewSocket; int NewSocket;
EFI_STATUS OpStatus; EFI_STATUS OpStatus;
struct sockaddr RemoteAddress; struct sockaddr_in6 RemoteAddress;
socklen_t RemoteAddressLength; socklen_t RemoteAddressLength;
EFI_STATUS Status; EFI_STATUS Status;
@ -355,14 +355,15 @@ PortWork (
// //
// Determine if this is a connection attempt // Determine if this is a connection attempt
// //
if ( SocketFD == pWebServer->HttpListenPort ) { if (( SocketFD == pWebServer->HttpListenPort )
|| ( SocketFD == pWebServer->HttpListenPort6 )) {
// //
// Handle connection attempts // Handle connection attempts
// Accepts arrive as read events // Accepts arrive as read events
// //
RemoteAddressLength = sizeof ( RemoteAddress ); RemoteAddressLength = sizeof ( RemoteAddress );
NewSocket = accept ( SocketFD, NewSocket = accept ( SocketFD,
&RemoteAddress, (struct sockaddr *)&RemoteAddress,
&RemoteAddressLength ); &RemoteAddressLength );
if ( -1 != NewSocket ) { if ( -1 != NewSocket ) {
if ( 0 != 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 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 some time to get the IP address and initialize the upper layers of
the network stack. the network stack.
@ -572,195 +573,93 @@ SocketPoll (
coming and going of the network connections until the last network coming and going of the network connections until the last network
connection is broken. 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 VOID
WebServerTimer ( WebServerListen (
IN DT_WEB_SERVER * pWebServer IN DT_WEB_SERVER * pWebServer,
IN sa_family_t AddressFamily,
IN int Protocol,
IN UINT16 HttpPort,
OUT int * pPort
) )
{ {
UINT16 HttpPort; union {
struct sockaddr_in WebServerAddress; struct sockaddr_in v4;
struct sockaddr_in6 v6;
} WebServerAddress;
int SocketStatus; int SocketStatus;
EFI_STATUS Status; 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 { * pPort = socket ( AddressFamily, SOCK_STREAM, Protocol );
do { if ( -1 != *pPort ) {
// //
// Complete the client operations // Build the socket address
// //
SocketPoll ( pWebServer ); ZeroMem ( &WebServerAddress, sizeof ( WebServerAddress ));
if ( AF_INET == AddressFamily ) {
// WebServerAddress.v4.sin_len = sizeof ( WebServerAddress.v4 );
// Wait for a while WebServerAddress.v4.sin_family = AddressFamily;
// WebServerAddress.v4.sin_port = htons ( HttpPort );
Status = gBS->CheckEvent ( pWebServer->TimerEvent ); }
} while ( EFI_SUCCESS != Status ); 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, SocketStatus = bind ( *pPort,
SOCK_STREAM, (struct sockaddr *) &WebServerAddress,
IPPROTO_TCP ); WebServerAddress.v4.sin_len );
if ( -1 != pWebServer->HttpListenPort ) { if ( -1 != SocketStatus ) {
// //
// Set the socket address // Enable connections to the HTTP port
// //
ZeroMem ( &WebServerAddress, sizeof ( WebServerAddress )); SocketStatus = listen ( *pPort, SOMAXCONN );
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 );
if ( -1 != SocketStatus ) { if ( -1 != SocketStatus ) {
// //
// Enable connections to the HTTP port // Add the HTTP port to the list of ports to poll
// //
SocketStatus = listen ( pWebServer->HttpListenPort, Status = PortAdd ( pWebServer, *pPort );
SOMAXCONN ); if ( EFI_ERROR ( Status )) {
} SocketStatus = -1;
}
// else {
// Release the socket if necessary DEBUG (( DEBUG_PORT_WORK,
// "Listening on Tcp%d:%d\r\n",
if ( -1 == SocketStatus ) { ( AF_INET == AddressFamily ) ? 4 : 6,
close ( pWebServer->HttpListenPort ); HttpPort ));
pWebServer->HttpListenPort = -1; }
} }
} }
// //
// Wait until the socket is open // Release the socket if necessary
// //
}while ( -1 == pWebServer->HttpListenPort ); if ( -1 == SocketStatus ) {
close ( *pPort );
DEBUG (( DEBUG_SERVER_TIMER, "Exiting WebServerTimer\r\n" )); *pPort = -1;
}
/**
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 ));
} }
} }
// DEBUG (( DEBUG_SERVER_LISTEN, "Exiting WebServerListen\r\n" ));
// Return the operation status
//
DBG_EXIT_STATUS ( Status );
return Status;
} }
/**
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. Entry point for the web server application.
@ -776,8 +675,19 @@ main (
IN char **Argv IN char **Argv
) )
{ {
UINT16 HttpPort;
UINTN Index;
DT_WEB_SERVER * pWebServer; DT_WEB_SERVER * pWebServer;
EFI_STATUS Status; 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 // Create a timer event to start HTTP port
@ -789,12 +699,18 @@ main (
NULL, NULL,
&pWebServer->TimerEvent ); &pWebServer->TimerEvent );
if ( !EFI_ERROR ( Status )) { 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 )) { if ( !EFI_ERROR ( Status )) {
// //
// Run the web server forever // 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 // Poll the network layer to create the HTTP port
// for the web server. More than one attempt may // for the web server. More than one attempt may
@ -802,45 +718,72 @@ main (
// the IP address and initialize the upper layers // the IP address and initialize the upper layers
// of the network stack. // of the network stack.
// //
WebServerTimer ( pWebServer ); if (( -1 == pWebServer->HttpListenPort )
|| ( -1 == pWebServer->HttpListenPort6 )) {
//
// Add the HTTP port to the list of ports
//
Status = PortAdd ( pWebServer, pWebServer->HttpListenPort );
if ( !EFI_ERROR ( Status )) {
//
// Poll the sockets for activity
//
do { 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 ) { do {
close ( pWebServer->HttpListenPort ); SocketPoll ( pWebServer );
pWebServer->HttpListenPort = -1; } while ( pWebServer->bRunning
} && ( -1 != pWebServer->HttpListenPort )
// && ( -1 != pWebServer->HttpListenPort6 ));
// TODO: Remove the following test code
// Exit when the network connection is broken //
// // Continue polling the network connections until both
break; // TCP4 and TCP6 are connected
} //
} while ( pWebServer->bRunning );
// //
// Done with the timer event // Stop the timer
// //
WebServerTimerStop ( pWebServer ); gBS->SetTimer ( pWebServer->TimerEvent,
Status = gBS->CloseEvent ( pWebServer->TimerEvent ); TimerCancel,
0 );
} }
//
// Done with the timer event
//
gBS->CloseEvent ( pWebServer->TimerEvent );
} }
// //

View File

@ -86,7 +86,7 @@
#define DEBUG_SOCKET_POLL 0x00080000 ///< Display the socket poll messages #define DEBUG_SOCKET_POLL 0x00080000 ///< Display the socket poll messages
#define DEBUG_PORT_WORK 0x00040000 ///< Display the port work 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_HTTP_PORT 0x00010000 ///< Display HTTP port related messages
#define DEBUG_REQUEST 0x00008000 ///< Display the HTTP request messages #define DEBUG_REQUEST 0x00008000 ///< Display the HTTP request messages
@ -173,9 +173,10 @@ typedef struct {
// //
// HTTP port management // HTTP port management
// //
BOOLEAN bTimerRunning; ///< Port creation timer status BOOLEAN bRunning; ///< Web server running
EFI_EVENT TimerEvent; ///< Timer to open HTTP port 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 // Client port management
@ -377,6 +378,23 @@ DxeServicesTablePage (
OUT BOOLEAN * pbDone 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 Respond with the firmware status
@ -445,6 +463,23 @@ IndexPage (
OUT BOOLEAN * pbDone 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 Page to reboot the system
@ -723,7 +758,7 @@ EFI_STATUS
HttpSendIpAddress ( HttpSendIpAddress (
IN int SocketFD, IN int SocketFD,
IN WSDT_PORT * pPort, IN WSDT_PORT * pPort,
IN struct sockaddr_in * pAddress IN struct sockaddr_in6 * pAddress
); );
/** /**

View File

@ -8,7 +8,7 @@
# license agreement # 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 # This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance # under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such # with the terms of the license. Except as permitted by such
@ -40,12 +40,14 @@
ConfigurationTable.c ConfigurationTable.c
DhcpOptions.c DhcpOptions.c
DxeServicesTable.c DxeServicesTable.c
Exit.c
Firmware.c Firmware.c
Handles.c Handles.c
Hello.c Hello.c
HTTP.c HTTP.c
Index.c Index.c
PageList.c PageList.c
Ports.c
Reboot.c Reboot.c
RuntimeServicesTable.c RuntimeServicesTable.c
SystemTable.c SystemTable.c
@ -53,10 +55,10 @@
[Pcd] [Pcd]
gStdLibTokenSpaceGuid.WebServer_HttpPort gAppPkgTokenSpaceGuid.WebServer_HttpPort
[Packages] [Packages]
AppPkg/AppPkg.dec
MdePkg/MdePkg.dec MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec MdeModulePkg/MdeModulePkg.dec
ShellPkg/ShellPkg.dec ShellPkg/ShellPkg.dec
@ -68,14 +70,14 @@
BsdSocketLib BsdSocketLib
DebugLib DebugLib
DevShell DevShell
# EfiSocketLib EfiSocketLib
LibC LibC
ShellLib ShellLib
ShellCEntryLib ShellCEntryLib
UefiBootServicesTableLib UefiBootServicesTableLib
UefiLib UefiLib
UefiRuntimeServicesTableLib UefiRuntimeServicesTableLib
UseSocketDxe # UseSocketDxe
[Guids] [Guids]
gEfiAcpi10TableGuid gEfiAcpi10TableGuid