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

View File

@ -8,7 +8,7 @@
# license agreement
#
#
# Copyright (c) 20011 Intel Corporation. All rights reserved
# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such
@ -39,10 +39,11 @@
[Pcd]
gStdLibTokenSpaceGuid.DataSource_Port
gAppPkgTokenSpaceGuid.DataSource_Port
[Packages]
AppPkg/AppPkg.dec
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec
StdLib/StdLib.dec

View File

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

View File

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

View File

@ -8,7 +8,7 @@
# license agreement
#
#
# Copyright (c) 20011 Intel Corporation. All rights reserved
# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement
#
#
# Copyright (c) 20011 Intel Corporation. All rights reserved
# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such

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
#
#
# Copyright (c) 20011 Intel Corporation. All rights reserved
# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement
#
#
# Copyright (c) 20011 Intel Corporation. All rights reserved
# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement
#
#
# Copyright (c) 20011 Intel Corporation. All rights reserved
# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement
#
#
# Copyright (c) 20011 Intel Corporation. All rights reserved
# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement
#
#
# Copyright (c) 20011 Intel Corporation. All rights reserved
# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement
#
#
# Copyright (c) 20011 Intel Corporation. All rights reserved
# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement
#
#
# Copyright (c) 20011 Intel Corporation. All rights reserved
# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement
#
#
# Copyright (c) 20011 Intel Corporation. All rights reserved
# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement
#
#
# Copyright (c) 20011 Intel Corporation. All rights reserved
# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement
#
#
# Copyright (c) 20011 Intel Corporation. All rights reserved
# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such

View File

@ -8,7 +8,7 @@
# license agreement
#
#
# Copyright (c) 20011 Intel Corporation. All rights reserved
# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/** @file
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
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
@ -16,6 +16,7 @@
#define _TFTP_SERVER_H_
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Uefi.h>
@ -24,29 +25,33 @@
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/TimerLib.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Protocol/BlockIo.h>
#include <netinet/in.h>
#include <netinet6/in6.h>
#include <sys/EfiSysCall.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/Stat.h>
//------------------------------------------------------------------------------
// Macros
//------------------------------------------------------------------------------
#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
#define DBG_ENTER() DEBUG (( DEBUG_INFO, "Entering " __FUNCTION__ "\n" )) ///< Display routine entry
#define DBG_EXIT() DEBUG (( DEBUG_INFO, "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_HEX(Status) DEBUG (( DEBUG_INFO, "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_TF(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" )) ///< Display routine with TRUE/FALSE value
#define DBG_ENTER() DEBUG (( DEBUG_ENTER_EXIT, "Entering " __FUNCTION__ "\n" )) ///< Display routine entry
#define DBG_EXIT() DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ "\n" )) ///< Display routine exit
#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_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status )) ///< Display routine exit with hex 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_ENTER_EXIT, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" )) ///< Display routine with TRUE/FALSE value
#else // _MSC_VER
#define DBG_ENTER()
#define DBG_EXIT()
@ -62,14 +67,22 @@
// Constants
//------------------------------------------------------------------------------
#define DEBUG_PORT_WORK 0x40000000 ///< Display the port work messages
#define DEBUG_SERVER_TIMER 0x20000000 ///< Display the socket poll messages
#define DEBUG_TFTP_PORT 0x10000000 ///< Display the TFTP port messages
#define DEBUG_TFTP_REQUEST 0x08000000 ///< Display the TFTP request messages
#define DEBUG_TX 0x04000000 ///< Display transmit messages
#define DEBUG_SOCKET_POLL 0x02000000 ///< Display the socket poll messages
#define DEBUG_RX 0x01000000 ///< Display receive messages
#define DEBUG_TFTP_ACK 0x00800000 ///< Display the TFTP ACK messages
#define ACK_SHIFT 4 ///< Number of samples in ACK average
#define DEBUG_WINDOW 0x00000001 ///< Display the window messages
#define DEBUG_TX_PACKET 0x00000002 ///< Display the transmit packet messages
#define DEBUG_FILE_BUFFER 0x00000004 ///< Display the file buffer messages
#define DEBUG_SERVER_TIMER 0x00000008 ///< Display the socket poll messages
#define DEBUG_TFTP_REQUEST 0x00000010 ///< Display the TFTP request 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 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_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
//------------------------------------------------------------------------------
/**
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
**/
@ -135,33 +170,49 @@ typedef struct _TSDT_CONNECTION_CONTEXT {
//
// Remote connection management
//
TSDT_CONNECTION_CONTEXT * pNext; ///< Next context in the connection list
struct sockaddr_in RemoteAddress; ///< Remote address
//
// 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
TSDT_CONNECTION_CONTEXT * pNext; ///< Next context in the connection list
struct sockaddr_in6 RemoteAddress; ///< Remote address
int SocketFd; ///< Socket file descriptor
//
// 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 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
UINT8 * pFill; ///< Next portion of the buffer to fill
UINT8 * pBuffer; ///< Pointer into 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
//
ssize_t TxBytes; ///< Bytes in the TX buffer
UINT8 TxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Transmit buffer
TFTP_PACKET * pFreeList; ///< List of free packets
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;
/**
@ -175,20 +226,32 @@ typedef struct {
//
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
//
BOOLEAN bTimerRunning; ///< Port creation timer status
EFI_EVENT TimerEvent; ///< Timer to open TFTP port
struct pollfd TftpPort; ///< Poll descriptor for the TFTP port
struct sockaddr_in TftpServerAddress; ///< Address of the local TFTP server
int Udpv4Index; ///< Entry for UDPv4
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
//
struct sockaddr_in RemoteAddress; ///< Remote address
ssize_t RxBytes; ///< Receive data length in bytes
UINT8 RxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Receive buffer
union {
struct sockaddr_in v4; ///< UDP4 address
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
@ -204,6 +267,92 @@ extern TSDT_TFTP_SERVER mTftpServer;
// 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
@ -224,105 +373,56 @@ TftpOptionValue (
@param [in] pTftpServer The TFTP server control structure address.
@param [in] pContext Connection context structure address
@param [in] SocketFd Socket file descriptor
**/
VOID
TftpProcessRequest (
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] pContext The context structure address.
@param [in] Error Error number for the packet
@param [in] pError Zero terminated error string address
@param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
@param [in] pContext Connection context structure address
@param [in] SocketFd Socket file descriptor
@retval EFI_SUCCESS Message processed successfully
@retval TRUE if the context should be closed
**/
EFI_STATUS
TftpSendError (
BOOLEAN
TftpRead (
IN TSDT_TFTP_SERVER * pTftpServer,
IN TSDT_CONNECTION_CONTEXT * pContext,
IN UINT16 Error,
IN UINT8 * pError
IN int SocketFd
);
/**
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] pContext The context structure address.
@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.
@param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
@param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
@param [in] pPacket Address of a ::TFTP_PACKET structure
**/
VOID
TftpServerTimer (
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 (
WindowAck (
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
);

View File

@ -8,7 +8,7 @@
# license agreement
#
#
# Copyright (c) 20011 Intel Corporation. All rights reserved
# Copyright (c) 2011 Intel Corporation. All rights reserved
# This software and associated documentation (if any) is furnished
# under a license and may only be used or copied in accordance
# with the terms of the license. Except as permitted by such
@ -39,7 +39,17 @@
TftpServer.c
[Pcd]
gAppPkgTokenSpaceGuid.Tftp_AckLogBase
gAppPkgTokenSpaceGuid.Tftp_AckMultiplier
gAppPkgTokenSpaceGuid.Tftp_Bandwidth
gAppPkgTokenSpaceGuid.Tftp_HighSpeed
gAppPkgTokenSpaceGuid.Tftp_MaxRetry
gAppPkgTokenSpaceGuid.Tftp_MaxTimeoutInSec
[Packages]
AppPkg/AppPkg.dec
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec
StdLib/StdLib.dec
@ -54,6 +64,7 @@
LibC
ShellLib
ShellCEntryLib
TimerLib
UefiBootServicesTableLib
UefiLib
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;
EFI_STATUS Status;
socklen_t LengthInBytes;
struct sockaddr_in LocalAddress;
struct sockaddr_in RemoteAddress;
struct sockaddr_in6 LocalAddress;
struct sockaddr_in6 RemoteAddress;
DBG_ENTER ( );
@ -413,12 +413,13 @@ HttpPageTrailer (
LengthInBytes = sizeof ( LocalAddress );
RetVal = getsockname ( SocketFD, (struct sockaddr *)&LocalAddress, &LengthInBytes );
if ( 0 == RetVal ) {
LengthInBytes = sizeof ( LocalAddress );
RetVal = getpeername ( SocketFD, (struct sockaddr *)&RemoteAddress, &LengthInBytes );
if ( 0 == RetVal ) {
//
// Seperate the body from the trailer
//
Status = HttpSendAnsiString ( SocketFD, pPort, " <hr>\r\n" );
Status = HttpSendAnsiString ( SocketFD, pPort, " <hr>\r\n<code>" );
if ( EFI_ERROR ( Status )) {
break;
}
@ -438,7 +439,7 @@ HttpPageTrailer (
if ( EFI_ERROR ( Status )) {
break;
}
Status = HttpSendAnsiString ( SocketFD, pPort, "\r\n" );
Status = HttpSendAnsiString ( SocketFD, pPort, "</code>\r\n" );
if ( EFI_ERROR ( Status )) {
break;
}
@ -1213,7 +1214,7 @@ HttpSendHexBits (
//
Digit = (UINT32)(( Value >> Shift ) & 0xf );
if ( 10 <= Digit ) {
Digit += 'A' - '0' - 10;
Digit += 'a' - '0' - 10;
}
//
@ -1274,7 +1275,7 @@ HttpSendHexValue (
//
Digit = (UINT32)(( Value >> Shift ) & 0xf );
if ( 10 <= Digit ) {
Digit += 'A' - '0' - 10;
Digit += 'a' - '0' - 10;
}
//
@ -1305,6 +1306,112 @@ HttpSendHexValue (
}
/**
Output an IP6 address value to the HTML page
@param [in] SocketFD Socket file descriptor
@param [in] pPort The WSDT_PORT structure address
@param [in] Value Value to display
@param [in] bFirstValue TRUE if first value
@param [in] bLastValue TRUE if last value
@param [in] bZeroSuppression TRUE while zeros are being suppressed
@param [in] pbZeroSuppression Address to receive TRUE when zero suppression
has started, use NULL if next colon value not
needed.
@retval EFI_SUCCESS Successfully displayed the address
**/
EFI_STATUS
HttpSendIp6Value (
IN int SocketFD,
IN WSDT_PORT * pPort,
IN UINT16 Value,
IN BOOLEAN bFirstValue,
IN BOOLEAN bLastValue,
IN BOOLEAN bZeroSuppression,
IN BOOLEAN * pbZeroSuppression
)
{
BOOLEAN bZeroSuppressionStarting;
UINT32 Digit;
EFI_STATUS Status;
//
// Use break instead of goto
//
bZeroSuppressionStarting = FALSE;
Status = EFI_SUCCESS;
for ( ; ; ) {
//
// Display the leading colon if necessary
//
if ( bZeroSuppression && ( bLastValue || ( 0 != Value ))) {
Status = HttpSendByte ( SocketFD, pPort, ':' );
if ( EFI_ERROR ( Status )) {
break;
}
}
//
// Skip over a series of zero values
//
bZeroSuppressionStarting = (BOOLEAN)( 0 == Value );
if ( !bZeroSuppressionStarting ) {
//
// Display the value
//
Digit = ( Value >> 4 ) & 0xf;
Status = HttpSendHexValue ( SocketFD,
pPort,
Digit );
if ( EFI_ERROR ( Status )) {
break;
}
Digit = Value & 0xf;
Status = HttpSendHexValue ( SocketFD,
pPort,
Digit );
if ( EFI_ERROR ( Status )) {
break;
}
Digit = ( Value >> 12 ) & 0xf;
Status = HttpSendHexValue ( SocketFD,
pPort,
Digit );
if ( EFI_ERROR ( Status )) {
break;
}
Digit = ( Value >> 8 ) & 0xf;
Status = HttpSendHexValue ( SocketFD,
pPort,
Digit );
if ( EFI_ERROR ( Status )) {
break;
}
}
//
// Display the trailing colon if necessary
//
if (( !bLastValue ) && ( bFirstValue || ( 0 != Value ))) {
Status = HttpSendByte ( SocketFD, pPort, ':' );
}
break;
}
//
// Return the next colon display
if ( NULL != pbZeroSuppression ) {
*pbZeroSuppression = bZeroSuppressionStarting;
}
//
// Return the operation status
//
return Status;
}
/**
Output an IP address to the HTML page
@ -1318,41 +1425,109 @@ EFI_STATUS
HttpSendIpAddress (
IN int SocketFD,
IN WSDT_PORT * pPort,
IN struct sockaddr_in * pAddress
IN struct sockaddr_in6 * pAddress
)
{
BOOLEAN bZeroSuppression;
UINT32 Index;
struct sockaddr_in * pIpv4;
struct sockaddr_in6 * pIpv6;
UINT16 PortNumber;
EFI_STATUS Status;
//
// Output the IPv4 address
// Use break instead of goto
//
Status = HttpSendValue ( SocketFD, pPort, (UINT8)pAddress->sin_addr.s_addr );
if ( !EFI_ERROR ( Status )) {
Status = HttpSendByte ( SocketFD, pPort, '.' );
if ( !EFI_ERROR ( Status )) {
Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pAddress->sin_addr.s_addr >> 8 ));
if ( !EFI_ERROR ( Status )) {
Status = HttpSendByte ( SocketFD, pPort, '.' );
if ( !EFI_ERROR ( Status )) {
Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pAddress->sin_addr.s_addr >> 16 ));
if ( !EFI_ERROR ( Status )) {
Status = HttpSendByte ( SocketFD, pPort, '.' );
if ( !EFI_ERROR ( Status )) {
Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pAddress->sin_addr.s_addr >> 24 ));
if ( !EFI_ERROR ( Status )) {
//
// Output the port number
//
Status = HttpSendByte ( SocketFD, pPort, ':' );
if ( !EFI_ERROR ( Status )) {
Status = HttpSendValue ( SocketFD, pPort, htons ( pAddress->sin_port ));
}
}
}
}
for ( ; ; ) {
//
// Determine the type of address
//
if ( AF_INET6 == pAddress->sin6_family ) {
pIpv6 = pAddress;
//
// Display the address in RFC2732 format
//
bZeroSuppression = FALSE;
Status = HttpSendByte ( SocketFD, pPort, '[' );
if ( EFI_ERROR ( Status )) {
break;
}
for ( Index = 0; 8 > Index; Index++ ) {
Status = HttpSendIp6Value ( SocketFD,
pPort,
pIpv6->sin6_addr.__u6_addr.__u6_addr16[ Index ],
(BOOLEAN)( 0 == Index ),
(BOOLEAN)( 7 == Index ),
bZeroSuppression,
&bZeroSuppression );
if ( EFI_ERROR ( Status )) {
break;
}
}
if ( EFI_ERROR ( Status )) {
break;
}
//
// Separate the port number
//
Status = HttpSendByte ( SocketFD, pPort, ']' );
//
// Get the port number
//
PortNumber = pIpv6->sin6_port;
}
else {
//
// Output the IPv4 address
//
pIpv4 = (struct sockaddr_in *)pAddress;
Status = HttpSendValue ( SocketFD, pPort, (UINT8)pIpv4->sin_addr.s_addr );
if ( EFI_ERROR ( Status )) {
break;
}
Status = HttpSendByte ( SocketFD, pPort, '.' );
if ( EFI_ERROR ( Status )) {
break;
}
Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pIpv4->sin_addr.s_addr >> 8 ));
if ( EFI_ERROR ( Status )) {
break;
}
Status = HttpSendByte ( SocketFD, pPort, '.' );
if ( EFI_ERROR ( Status )) {
break;
}
Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pIpv4->sin_addr.s_addr >> 16 ));
if ( EFI_ERROR ( Status )) {
break;
}
Status = HttpSendByte ( SocketFD, pPort, '.' );
if ( EFI_ERROR ( Status )) {
break;
}
Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pIpv4->sin_addr.s_addr >> 24 ));
//
// Get the port number
//
PortNumber = pIpv4->sin_port;
}
if ( EFI_ERROR ( Status )) {
break;
}
//
// Display the port number
//
Status = HttpSendByte ( SocketFD, pPort, ':' );
if ( EFI_ERROR ( Status )) {
break;
}
Status = HttpSendValue ( SocketFD, pPort, htons ( PortNumber ));
break;
}
//

View File

@ -44,10 +44,12 @@ CONST DT_PAGE mPageList[] = {
{ L"/DhcpOptions", DhcpOptionsPage, L"DHCP Options" }, ///< Display the DHCP options
{ PAGE_ACPI_DSDT, AcpiDsdtPage, L"DSDT - Differentiated System Description Table" }, ///< Format DSDT
{ PAGE_DXE_SERVICES_TABLE, DxeServicesTablePage, L"DXE Services Table" }, ///< Format DXE services table
{ L"/Exit", ExitPage, L"Exit the web server" }, ///< Exit the web server application
{ PAGE_ACPI_FADT, AcpiFadtPage, L"FADT - Fixed ACPI Description Table" }, ///< Format FADT
{ L"/Firmware", FirmwarePage, L"Firmware" }, ///< Firmware status
{ L"/Handles", HandlePage, L"Display handles and associated protocol GUIDs" }, ///< Handle database page
{ L"/Hello", HelloPage, L"Hello World" }, ///< Hello world page
{ L"/Ports", PortsPage, L"Display web-server ports" },///< Web-server ports page
{ L"/Reboot", RebootPage, L"Reboot the sytem" }, ///< Reboot page
{ PAGE_ACPI_RSDP_10B, AcpiRsdp10Page, L"RSDP 1.0b - ACPI Root System Description Pointer" }, ///< Format RSDP 1.0b table
{ PAGE_ACPI_RSDP_30, AcpiRsdp30Page, L"RSDP 3.0 - ACPI Root System Description Pointer" }, ///< Format RSDP 3.0 table

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;
int NewSocket;
EFI_STATUS OpStatus;
struct sockaddr RemoteAddress;
struct sockaddr_in6 RemoteAddress;
socklen_t RemoteAddressLength;
EFI_STATUS Status;
@ -355,14 +355,15 @@ PortWork (
//
// Determine if this is a connection attempt
//
if ( SocketFD == pWebServer->HttpListenPort ) {
if (( SocketFD == pWebServer->HttpListenPort )
|| ( SocketFD == pWebServer->HttpListenPort6 )) {
//
// Handle connection attempts
// Accepts arrive as read events
//
RemoteAddressLength = sizeof ( RemoteAddress );
NewSocket = accept ( SocketFD,
&RemoteAddress,
(struct sockaddr *)&RemoteAddress,
&RemoteAddressLength );
if ( -1 != NewSocket ) {
if ( 0 != NewSocket ) {
@ -561,9 +562,9 @@ SocketPoll (
/**
Create the HTTP port for the web server
Create an HTTP port for the web server
This routine polls the network layer to create the HTTP port for the
This routine polls the network layer to create an HTTP port for the
web server. More than one attempt may be necessary since it may take
some time to get the IP address and initialize the upper layers of
the network stack.
@ -572,195 +573,93 @@ SocketPoll (
coming and going of the network connections until the last network
connection is broken.
@param [in] pWebServer The web server control structure address.
@param [in] pWebServer The web server control structure address.
@param [in] AddressFamily Address family for the network connection
@param [in] Protocol Protocol to use for the network connection
@param [in] HttpPort Port number for the HTTP connection
@param [out] pPort Address of the port
**/
VOID
WebServerTimer (
IN DT_WEB_SERVER * pWebServer
WebServerListen (
IN DT_WEB_SERVER * pWebServer,
IN sa_family_t AddressFamily,
IN int Protocol,
IN UINT16 HttpPort,
OUT int * pPort
)
{
UINT16 HttpPort;
struct sockaddr_in WebServerAddress;
union {
struct sockaddr_in v4;
struct sockaddr_in6 v6;
} WebServerAddress;
int SocketStatus;
EFI_STATUS Status;
DEBUG (( DEBUG_SERVER_TIMER, "Entering WebServerTimer\r\n" ));
DEBUG (( DEBUG_SERVER_LISTEN, "Entering WebServerListen\r\n" ));
//
// Open the HTTP port on the server
// Attempt to create the socket for the web server
//
do {
do {
//
// Complete the client operations
//
SocketPoll ( pWebServer );
//
// Wait for a while
//
Status = gBS->CheckEvent ( pWebServer->TimerEvent );
} while ( EFI_SUCCESS != Status );
* pPort = socket ( AddressFamily, SOCK_STREAM, Protocol );
if ( -1 != *pPort ) {
//
// Build the socket address
//
ZeroMem ( &WebServerAddress, sizeof ( WebServerAddress ));
if ( AF_INET == AddressFamily ) {
WebServerAddress.v4.sin_len = sizeof ( WebServerAddress.v4 );
WebServerAddress.v4.sin_family = AddressFamily;
WebServerAddress.v4.sin_port = htons ( HttpPort );
}
else {
WebServerAddress.v6.sin6_len = sizeof ( WebServerAddress.v6 );
WebServerAddress.v6.sin6_family = AddressFamily;
WebServerAddress.v6.sin6_port = htons ( HttpPort );
WebServerAddress.v6.sin6_scope_id = __IPV6_ADDR_SCOPE_GLOBAL;
}
//
// Attempt to create the socket for the web server
// Bind the socket to the HTTP port
//
pWebServer->HttpListenPort = socket ( AF_INET,
SOCK_STREAM,
IPPROTO_TCP );
if ( -1 != pWebServer->HttpListenPort ) {
SocketStatus = bind ( *pPort,
(struct sockaddr *) &WebServerAddress,
WebServerAddress.v4.sin_len );
if ( -1 != SocketStatus ) {
//
// Set the socket address
// Enable connections to the HTTP port
//
ZeroMem ( &WebServerAddress, sizeof ( WebServerAddress ));
HttpPort = PcdGet16 ( WebServer_HttpPort );
DEBUG (( DEBUG_HTTP_PORT,
"HTTP Port: %d\r\n",
HttpPort ));
WebServerAddress.sin_len = sizeof ( WebServerAddress );
WebServerAddress.sin_family = AF_INET;
WebServerAddress.sin_addr.s_addr = INADDR_ANY;
WebServerAddress.sin_port = htons ( HttpPort );
//
// Bind the socket to the HTTP port
//
SocketStatus = bind ( pWebServer->HttpListenPort,
(struct sockaddr *) &WebServerAddress,
WebServerAddress.sin_len );
SocketStatus = listen ( *pPort, SOMAXCONN );
if ( -1 != SocketStatus ) {
//
// Enable connections to the HTTP port
// Add the HTTP port to the list of ports to poll
//
SocketStatus = listen ( pWebServer->HttpListenPort,
SOMAXCONN );
}
//
// Release the socket if necessary
//
if ( -1 == SocketStatus ) {
close ( pWebServer->HttpListenPort );
pWebServer->HttpListenPort = -1;
Status = PortAdd ( pWebServer, *pPort );
if ( EFI_ERROR ( Status )) {
SocketStatus = -1;
}
else {
DEBUG (( DEBUG_PORT_WORK,
"Listening on Tcp%d:%d\r\n",
( AF_INET == AddressFamily ) ? 4 : 6,
HttpPort ));
}
}
}
//
// Wait until the socket is open
// Release the socket if necessary
//
}while ( -1 == pWebServer->HttpListenPort );
DEBUG (( DEBUG_SERVER_TIMER, "Exiting WebServerTimer\r\n" ));
}
/**
Start the web server port creation timer
@param [in] pWebServer The web server control structure address.
@retval EFI_SUCCESS The timer was successfully started.
@retval EFI_ALREADY_STARTED The timer is already running.
@retval Other The timer failed to start.
**/
EFI_STATUS
WebServerTimerStart (
IN DT_WEB_SERVER * pWebServer
)
{
EFI_STATUS Status;
UINT64 TriggerTime;
DBG_ENTER ( );
//
// Assume the timer is already running
//
Status = EFI_ALREADY_STARTED;
if ( !pWebServer->bTimerRunning ) {
//
// Compute the poll interval
//
TriggerTime = HTTP_PORT_POLL_DELAY * ( 1000 * 10 );
Status = gBS->SetTimer ( pWebServer->TimerEvent,
TimerPeriodic,
TriggerTime );
if ( !EFI_ERROR ( Status )) {
DEBUG (( DEBUG_HTTP_PORT, "HTTP port timer started\r\n" ));
//
// Mark the timer running
//
pWebServer->bTimerRunning = TRUE;
}
else {
DEBUG (( DEBUG_ERROR | DEBUG_HTTP_PORT,
"ERROR - Failed to start HTTP port timer, Status: %r\r\n",
Status ));
if ( -1 == SocketStatus ) {
close ( *pPort );
*pPort = -1;
}
}
//
// Return the operation status
//
DBG_EXIT_STATUS ( Status );
return Status;
DEBUG (( DEBUG_SERVER_LISTEN, "Exiting WebServerListen\r\n" ));
}
/**
Stop the web server port creation timer
@param [in] pWebServer The web server control structure address.
@retval EFI_SUCCESS The HTTP port timer is stopped
@retval Other Failed to stop the HTTP port timer
**/
EFI_STATUS
WebServerTimerStop (
IN DT_WEB_SERVER * pWebServer
)
{
EFI_STATUS Status;
DBG_ENTER ( );
//
// Assume the timer is stopped
//
Status = EFI_SUCCESS;
if ( pWebServer->bTimerRunning ) {
//
// Stop the port creation polling
//
Status = gBS->SetTimer ( pWebServer->TimerEvent,
TimerCancel,
0 );
if ( !EFI_ERROR ( Status )) {
DEBUG (( DEBUG_HTTP_PORT, "HTTP port timer stopped\r\n" ));
//
// Mark the timer stopped
//
pWebServer->bTimerRunning = FALSE;
}
else {
DEBUG (( DEBUG_ERROR | DEBUG_HTTP_PORT,
"ERROR - Failed to stop HTTP port timer, Status: %r\r\n",
Status ));
}
}
//
// Return the operation status
//
DBG_EXIT_STATUS ( Status );
return Status;
}
/**
Entry point for the web server application.
@ -776,8 +675,19 @@ main (
IN char **Argv
)
{
UINT16 HttpPort;
UINTN Index;
DT_WEB_SERVER * pWebServer;
EFI_STATUS Status;
UINT64 TriggerTime;
//
// Get the HTTP port
//
HttpPort = PcdGet16 ( WebServer_HttpPort );
DEBUG (( DEBUG_HTTP_PORT,
"HTTP Port: %d\r\n",
HttpPort ));
//
// Create a timer event to start HTTP port
@ -789,12 +699,18 @@ main (
NULL,
&pWebServer->TimerEvent );
if ( !EFI_ERROR ( Status )) {
Status = WebServerTimerStart ( pWebServer );
TriggerTime = HTTP_PORT_POLL_DELAY * ( 1000 * 10 );
Status = gBS->SetTimer ( pWebServer->TimerEvent,
TimerPeriodic,
TriggerTime );
if ( !EFI_ERROR ( Status )) {
//
// Run the web server forever
//
for ( ; ; ) {
pWebServer->HttpListenPort = -1;
pWebServer->HttpListenPort6 = -1;
pWebServer->bRunning = TRUE;
do {
//
// Poll the network layer to create the HTTP port
// for the web server. More than one attempt may
@ -802,45 +718,72 @@ main (
// the IP address and initialize the upper layers
// of the network stack.
//
WebServerTimer ( pWebServer );
//
// Add the HTTP port to the list of ports
//
Status = PortAdd ( pWebServer, pWebServer->HttpListenPort );
if ( !EFI_ERROR ( Status )) {
//
// Poll the sockets for activity
//
if (( -1 == pWebServer->HttpListenPort )
|| ( -1 == pWebServer->HttpListenPort6 )) {
do {
SocketPoll ( pWebServer );
} while ( -1 != pWebServer->HttpListenPort );
//
// Wait a while before polling for a connection
//
if ( EFI_SUCCESS != gBS->CheckEvent ( pWebServer->TimerEvent )) {
if ( 0 != pWebServer->Entries ) {
break;
}
gBS->WaitForEvent ( 1, &pWebServer->TimerEvent, &Index );
}
//
// The HTTP port failed the accept and was closed
//
//
// Poll for a network connection
//
if ( -1 == pWebServer->HttpListenPort ) {
WebServerListen ( pWebServer,
AF_INET,
IPPROTO_TCP,
HttpPort,
&pWebServer->HttpListenPort );
}
if ( -1 == pWebServer->HttpListenPort6 ) {
WebServerListen ( pWebServer,
AF_INET6,
IPPROTO_TCP,
HttpPort,
&pWebServer->HttpListenPort6 );
}
//
// Continue polling while both network connections are
// not present
//
} while ( 0 == pWebServer->Entries );
}
//
// Close the HTTP port if necessary
// Poll the sockets for activity while both network
// connections are connected
//
if ( -1 != pWebServer->HttpListenPort ) {
close ( pWebServer->HttpListenPort );
pWebServer->HttpListenPort = -1;
}
//
// TODO: Remove the following test code
// Exit when the network connection is broken
//
break;
}
do {
SocketPoll ( pWebServer );
} while ( pWebServer->bRunning
&& ( -1 != pWebServer->HttpListenPort )
&& ( -1 != pWebServer->HttpListenPort6 ));
//
// Continue polling the network connections until both
// TCP4 and TCP6 are connected
//
} while ( pWebServer->bRunning );
//
// Done with the timer event
// Stop the timer
//
WebServerTimerStop ( pWebServer );
Status = gBS->CloseEvent ( pWebServer->TimerEvent );
gBS->SetTimer ( pWebServer->TimerEvent,
TimerCancel,
0 );
}
//
// Done with the timer event
//
gBS->CloseEvent ( pWebServer->TimerEvent );
}
//

View File

@ -86,7 +86,7 @@
#define DEBUG_SOCKET_POLL 0x00080000 ///< Display the socket poll messages
#define DEBUG_PORT_WORK 0x00040000 ///< Display the port work messages
#define DEBUG_SERVER_TIMER 0x00020000 ///< Display the socket poll messages
#define DEBUG_SERVER_LISTEN 0x00020000 ///< Display the socket poll messages
#define DEBUG_HTTP_PORT 0x00010000 ///< Display HTTP port related messages
#define DEBUG_REQUEST 0x00008000 ///< Display the HTTP request messages
@ -173,9 +173,10 @@ typedef struct {
//
// HTTP port management
//
BOOLEAN bTimerRunning; ///< Port creation timer status
BOOLEAN bRunning; ///< Web server running
EFI_EVENT TimerEvent; ///< Timer to open HTTP port
int HttpListenPort; ///< File descriptor for the HTTP listen port
int HttpListenPort; ///< File descriptor for the HTTP listen port over TCP4
int HttpListenPort6; ///< File descriptor for the HTTP listen port over TCP6
//
// Client port management
@ -377,6 +378,23 @@ DxeServicesTablePage (
OUT BOOLEAN * pbDone
);
/**
Respond with the Exit page
@param [in] SocketFD The socket's file descriptor to add to the list.
@param [in] pPort The WSDT_PORT structure address
@param [out] pbDone Address to receive the request completion status
@retval EFI_SUCCESS The request was successfully processed
**/
EFI_STATUS
ExitPage (
IN int SocketFD,
IN WSDT_PORT * pPort,
OUT BOOLEAN * pbDone
);
/**
Respond with the firmware status
@ -445,6 +463,23 @@ IndexPage (
OUT BOOLEAN * pbDone
);
/**
Respond with the Ports page
@param [in] SocketFD The socket's file descriptor to add to the list.
@param [in] pPort The WSDT_PORT structure address
@param [out] pbDone Address to receive the request completion status
@retval EFI_SUCCESS The request was successfully processed
**/
EFI_STATUS
PortsPage (
IN int SocketFD,
IN WSDT_PORT * pPort,
OUT BOOLEAN * pbDone
);
/**
Page to reboot the system
@ -723,7 +758,7 @@ EFI_STATUS
HttpSendIpAddress (
IN int SocketFD,
IN WSDT_PORT * pPort,
IN struct sockaddr_in * pAddress
IN struct sockaddr_in6 * pAddress
);
/**

View File

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