Add Socket Library applications.
authordarylm503 <darylm503@6f19259b-4bc3-4df7-8a09-765794883524>
Sat, 30 Jul 2011 00:32:15 +0000 (00:32 +0000)
committerdarylm503 <darylm503@6f19259b-4bc3-4df7-8a09-765794883524>
Sat, 30 Jul 2011 00:32:15 +0000 (00:32 +0000)
Modify AppPkg.dsc file to include StdLib.inc which contains the Boilerplate text for Standard Library based Applications.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12062 6f19259b-4bc3-4df7-8a09-765794883524

45 files changed:
AppPkg/AppPkg.dsc
AppPkg/Applications/Sockets/DataSink/DataSink.c [new file with mode: 0644]
AppPkg/Applications/Sockets/DataSink/DataSink.inf [new file with mode: 0644]
AppPkg/Applications/Sockets/DataSource/DataSource.c [new file with mode: 0644]
AppPkg/Applications/Sockets/DataSource/DataSource.inf [new file with mode: 0644]
AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.c [new file with mode: 0644]
AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.inf [new file with mode: 0644]
AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.c [new file with mode: 0644]
AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.inf [new file with mode: 0644]
AppPkg/Applications/Sockets/GetHostByName/GetHostByName.c [new file with mode: 0644]
AppPkg/Applications/Sockets/GetHostByName/GetHostByName.inf [new file with mode: 0644]
AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.c [new file with mode: 0644]
AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.inf [new file with mode: 0644]
AppPkg/Applications/Sockets/GetNetByName/GetNetByName.c [new file with mode: 0644]
AppPkg/Applications/Sockets/GetNetByName/GetNetByName.inf [new file with mode: 0644]
AppPkg/Applications/Sockets/GetServByName/GetServByName.c [new file with mode: 0644]
AppPkg/Applications/Sockets/GetServByName/GetServByName.inf [new file with mode: 0644]
AppPkg/Applications/Sockets/GetServByPort/GetServByPort.c [new file with mode: 0644]
AppPkg/Applications/Sockets/GetServByPort/GetServByPort.inf [new file with mode: 0644]
AppPkg/Applications/Sockets/RecvDgram/RecvDgram.c [new file with mode: 0644]
AppPkg/Applications/Sockets/RecvDgram/RecvDgram.inf [new file with mode: 0644]
AppPkg/Applications/Sockets/SetHostName/SetHostName.c [new file with mode: 0644]
AppPkg/Applications/Sockets/SetHostName/SetHostName.inf [new file with mode: 0644]
AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.c [new file with mode: 0644]
AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.inf [new file with mode: 0644]
AppPkg/Applications/Sockets/TftpServer/TftpServer.c [new file with mode: 0644]
AppPkg/Applications/Sockets/TftpServer/TftpServer.h [new file with mode: 0644]
AppPkg/Applications/Sockets/TftpServer/TftpServer.inf [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/ACPI.c [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/BootServicesTable.c [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/ConfigurationTable.c [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/DhcpOptions.c [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/DxeServicesTable.c [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/Firmware.c [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/HTTP.c [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/Handles.c [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/Hello.c [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/Index.c [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/PageList.c [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/Reboot.c [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/RuntimeServicesTable.c [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/SystemTable.c [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/WebServer.c [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/WebServer.h [new file with mode: 0644]
AppPkg/Applications/Sockets/WebServer/WebServer.inf [new file with mode: 0644]

index 7bc8f85..59341ec 100644 (file)
@@ -41,6 +41,7 @@
   #\r
   UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf\r
   ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf\r
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf\r
   #\r
   # Common Libraries\r
   #\r
   UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf\r
   PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf\r
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
+\r
   ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf\r
   FileHandleLib|ShellPkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf\r
   SortLib|ShellPkg/Library/UefiSortLib/UefiSortLib.inf\r
-\r
-  #\r
-  # C Standard Libraries\r
-  #\r
-  LibC|StdLib/LibC/LibC.inf\r
-  LibStdLib|StdLib/LibC/StdLib/StdLib.inf\r
-  LibString|StdLib/LibC/String/String.inf\r
-  LibWchar|StdLib/LibC/Wchar/Wchar.inf\r
-  LibCType|StdLib/LibC/Ctype/Ctype.inf\r
-  LibTime|StdLib/LibC/Time/Time.inf\r
-  LibStdio|StdLib/LibC/Stdio/Stdio.inf\r
-  LibGdtoa|StdLib/LibC/gdtoa/gdtoa.inf\r
-  LibLocale|StdLib/LibC/Locale/Locale.inf\r
-  LibUefi|StdLib/LibC/Uefi/Uefi.inf\r
-  LibMath|StdLib/LibC/Math/Math.inf\r
-  LibSignal|StdLib/LibC/Signal/Signal.inf\r
-  LibNetUtil|StdLib/LibC/NetUtil/NetUtil.inf\r
-\r
-  # Libraries for device abstractions within the Standard C Library\r
-  # Applications should not directly access any functions defined in these libraries.\r
-  DevUtility|StdLib/LibC/Uefi/Devices/daUtility.inf\r
-  DevConsole|StdLib/LibC/Uefi/Devices/daConsole.inf\r
-  DevShell|StdLib/LibC/Uefi/Devices/daShell.inf\r
-\r
-[LibraryClasses.IA32]\r
-  TimerLib|PerformancePkg/Library/DxeTscTimerLib/DxeTscTimerLib.inf\r
-  # To run in an emulation environment, such as Nt32Pkg, comment out the TimerLib\r
-  # description above and un-comment the line below.\r
-#  TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf\r
-\r
-[LibraryClasses.X64]\r
-  TimerLib|PerformancePkg/Library/DxeTscTimerLib/DxeTscTimerLib.inf\r
-\r
-[LibraryClasses.IPF]\r
-  PalLib|MdePkg/Library/UefiPalLib/UefiPalLib.inf\r
-  TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf\r
+  PathLib|ShellPkg/Library/BasePathLib/BasePathLib.inf\r
 \r
 ###################################################################################################\r
 #\r
 ###################################################################################################\r
 \r
 [Components]\r
-# BaseLib and BaseMemoryLib need to be built with the /GL- switch when using the Microsoft\r
-# tool chain.  This is required so that the library functions can be resolved during\r
-# the second pass of the linker during Link-time-code-generation.\r
-###\r
-  MdePkg/Library/BaseLib/BaseLib.inf {\r
-    <BuildOptions>\r
-      MSFT:*_*_*_CC_FLAGS    = /X /Zc:wchar_t /GL-\r
-  }\r
-\r
-  MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf {\r
-    <BuildOptions>\r
-      MSFT:*_*_*_CC_FLAGS    = /X /Zc:wchar_t /GL-\r
-  }\r
 \r
 #### Sample Applications.\r
   AppPkg/Applications/Hello/Hello.inf        # No LibC includes or functions.\r
   AppPkg/Applications/Main/Main.inf          # Simple invocation. No other LibC functions.\r
   AppPkg/Applications/Enquire/Enquire.inf\r
 \r
-# After extracting the Python distribution, un-comment the following line to build Python.\r
+#### After extracting the Python distribution, un-comment the following line to build Python.\r
 #  AppPkg/Applications/Python/PythonCore.inf\r
 \r
-################################################################\r
+##########\r
+#    Socket Applications - LibC based\r
+##########\r
+  AppPkg/Applications/Sockets/DataSink/DataSink.inf\r
+  AppPkg/Applications/Sockets/DataSource/DataSource.inf\r
+#  SocketPkg/Application/FtpNew/FTP.inf\r
+  AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.inf\r
+  AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.inf\r
+  AppPkg/Applications/Sockets/GetHostByName/GetHostByName.inf\r
+  AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.inf\r
+  AppPkg/Applications/Sockets/GetNetByName/GetNetByName.inf\r
+  AppPkg/Applications/Sockets/GetServByName/GetServByName.inf\r
+  AppPkg/Applications/Sockets/GetServByPort/GetServByPort.inf\r
+  AppPkg/Applications/Sockets/RecvDgram/RecvDgram.inf\r
+#  SocketPkg/Application/route/route.inf\r
+  AppPkg/Applications/Sockets/SetHostName/SetHostName.inf\r
+  AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.inf\r
+  AppPkg/Applications/Sockets/TftpServer/TftpServer.inf\r
+  AppPkg/Applications/Sockets/WebServer/WebServer.inf {\r
+    <PcdsFixedAtBuild>\r
+      gStdLibTokenSpaceGuid.WebServer_HttpPort|80\r
+  }\r
+\r
+###################################################################################################\r
 #\r
-# See the additional comments below if you plan to run applications under the\r
-# Nt32 emulation environment.\r
+#       Include Boilerplate text required for building with the Standard Libraries.\r
 #\r
-\r
-[BuildOptions]\r
-  INTEL:*_*_*_CC_FLAGS      = /Qfreestanding\r
-   MSFT:*_*_*_CC_FLAGS      = /X /Zc:wchar_t\r
-    GCC:*_*_*_CC_FLAGS      = -ffreestanding -nostdinc -nostdlib\r
-\r
-# The Build Options, below, are only used when building the C library\r
-# to be run under an emulation environment, such as Nt32Pkg.  The clock()\r
-# system call is modified to return -1 indicating that it is unsupported.\r
-# Just uncomment the lines below and select the correct TimerLib instance, above.\r
-\r
-  # INTEL:*_*_IA32_CC_FLAGS     = /D NT32dvm\r
-  #  MSFT:*_*_IA32_CC_FLAGS     = /D NT32dvm\r
-  #   GCC:*_*_IA32_CC_FLAGS     = -DNT32dvm\r
+###################################################################################################\r
+!include StdLib/StdLib.inc\r
diff --git a/AppPkg/Applications/Sockets/DataSink/DataSink.c b/AppPkg/Applications/Sockets/DataSink/DataSink.c
new file mode 100644 (file)
index 0000000..911cf36
--- /dev/null
@@ -0,0 +1,1029 @@
+/** @file\r
+  Data source for network testing.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <errno.h>\r
+#include <Uefi.h>\r
+\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <netinet/in.h>\r
+\r
+#include <sys/EfiSysCall.h>\r
+#include <sys/poll.h>\r
+#include <sys/socket.h>\r
+\r
+\r
+#define MAX_CONNECTIONS       ( 1 + 16 )  ///<  Maximum number of client connections\r
+#define RANGE_SWITCH                2048  ///<  Switch display ranges\r
+#define DATA_RATE_UPDATE_SHIFT      2     ///<  2n seconds between updates\r
+#define AVERAGE_SHIFT_COUNT ( 6 - DATA_RATE_UPDATE_SHIFT )  ///<  2n samples in average\r
+\r
+#define TPL_DATASINK        TPL_CALLBACK  ///<  Synchronization TPL\r
+\r
+#define PACKET_SIZE                 1448  ///<  Size of data packets\r
+#define DATA_BUFFER_SIZE    (( 65536 / PACKET_SIZE ) * PACKET_SIZE )  ///<  Buffer size in bytes\r
+\r
+typedef struct _DT_PORT {\r
+  UINT64 BytesAverage;\r
+  UINT64 BytesPrevious;\r
+  UINT64 BytesTotal;\r
+  struct sockaddr_in RemoteAddress;\r
+  UINT64 Samples;\r
+} DT_PORT;\r
+\r
+volatile BOOLEAN bTick;\r
+BOOLEAN bTimerRunning;\r
+struct sockaddr_in LocalAddress;\r
+EFI_EVENT pTimer;\r
+int ListenSocket;\r
+UINT8 Buffer [ DATA_BUFFER_SIZE ];\r
+struct pollfd PollFd [ MAX_CONNECTIONS ];\r
+DT_PORT Port [ MAX_CONNECTIONS ];\r
+nfds_t MaxPort;\r
+\r
+\r
+//\r
+//  Forward routine declarations\r
+//\r
+EFI_STATUS TimerStart ( UINTN Milliseconds );\r
+\r
+\r
+/**\r
+  Check for control C entered at console\r
+\r
+  @retval  EFI_SUCCESS  Control C not entered\r
+  @retval  EFI_ABORTED  Control C entered\r
+**/\r
+EFI_STATUS\r
+ControlCCheck (\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Assume no user intervention\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Display user stop request\r
+  //\r
+  if ( EFI_ERROR ( Status )) {\r
+    DEBUG (( DEBUG_INFO,\r
+              "User stop request!\r\n" ));\r
+  }\r
+\r
+  //\r
+  //  Return the check status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Accept a socket connection\r
+\r
+  @retval  EFI_SUCCESS      The application is running normally\r
+  @retval  EFI_NOT_STARTED  Error with the listen socket\r
+  @retval  Other            The user stopped the application\r
+**/\r
+EFI_STATUS\r
+SocketAccept (\r
+  )\r
+{\r
+  INT32 SocketStatus;\r
+  EFI_STATUS Status;\r
+  INTN Index;\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  Status = EFI_DEVICE_ERROR;\r
+\r
+  //\r
+  //  Bind to the local address\r
+  //\r
+  SocketStatus = bind ( ListenSocket,\r
+                        (struct sockaddr *) &LocalAddress,\r
+                        LocalAddress.sin_len );\r
+  if ( 0 == SocketStatus ) {\r
+    //\r
+    //  Start listening on the local socket\r
+    //\r
+    SocketStatus = listen ( ListenSocket, 5 );\r
+    if ( 0 == SocketStatus ) {\r
+      //\r
+      //  Local socket in the listen state\r
+      //\r
+      Status = EFI_SUCCESS;\r
+\r
+      //\r
+      //  Allocate a port\r
+      //\r
+      Index = MaxPort++;\r
+      PollFd [ Index ].fd = ListenSocket;\r
+      PollFd [ Index ].events = POLLRDNORM | POLLHUP;\r
+      PollFd [ Index ].revents = 0;\r
+      Port [ Index ].BytesAverage = 0;\r
+      Port [ Index ].BytesPrevious = 0;\r
+      Port [ Index ].BytesTotal = 0;\r
+      Port [ Index ].Samples = 0;\r
+      Port [ Index ].RemoteAddress.sin_len = 0;\r
+      Port [ Index ].RemoteAddress.sin_family = 0;\r
+      Port [ Index ].RemoteAddress.sin_port = 0;\r
+      Port [ Index ].RemoteAddress.sin_addr.s_addr= 0;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Close the socket\r
+\r
+  @retval  EFI_SUCCESS  The application is running normally\r
+  @retval  Other        The user stopped the application\r
+**/\r
+EFI_STATUS\r
+SocketClose (\r
+  )\r
+{\r
+  INT32 CloseStatus;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Determine if the socket is open\r
+  //\r
+  Status = EFI_DEVICE_ERROR;\r
+  if ( -1 != ListenSocket ) {\r
+    //\r
+    //  Attempt to close the socket\r
+    //\r
+    CloseStatus = close ( ListenSocket );\r
+    if ( 0 == CloseStatus ) {\r
+      DEBUG (( DEBUG_INFO,\r
+                "0x%08x: Socket closed\r\n",\r
+                ListenSocket ));\r
+      ListenSocket = -1;\r
+      Status = EFI_SUCCESS;\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR: Failed to close socket, errno: %d\r\n",\r
+                errno ));\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Create the socket\r
+\r
+  @retval  EFI_SUCCESS  The application is running normally\r
+  @retval  Other        The user stopped the application\r
+**/\r
+EFI_STATUS\r
+SocketNew (\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Get the port number\r
+  //\r
+  ZeroMem ( &LocalAddress, sizeof ( LocalAddress ));\r
+  LocalAddress.sin_len = sizeof ( LocalAddress );\r
+  LocalAddress.sin_family = AF_INET;\r
+  LocalAddress.sin_port = htons ( PcdGet16 ( DataSource_Port ));\r
+  \r
+  //\r
+  //  Loop creating the socket\r
+  //\r
+  DEBUG (( DEBUG_INFO,\r
+            "Creating the socket\r\n" ));\r
+\r
+  //\r
+  //  Check for user stop request\r
+  //\r
+  Status = ControlCCheck ( );\r
+  if ( !EFI_ERROR ( Status )) {\r
+    //\r
+    //  Attempt to create the socket\r
+    //\r
+    ListenSocket = socket ( AF_INET,\r
+                            SOCK_STREAM,\r
+                            IPPROTO_TCP );\r
+    if ( -1 != ListenSocket ) {\r
+      DEBUG (( DEBUG_INFO,\r
+                "0x%08x: Socket created\r\n",\r
+                ListenSocket ));\r
+    }\r
+    else\r
+    {\r
+      Status = EFI_NOT_STARTED;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Poll the socket for more work\r
+\r
+  @retval  EFI_SUCCESS      The application is running normally\r
+  @retval  EFI_NOT_STARTED  Listen socket error\r
+  @retval  Other            The user stopped the application\r
+**/\r
+EFI_STATUS\r
+SocketPoll (\r
+  )\r
+{\r
+  BOOLEAN bRemoveSocket;\r
+  BOOLEAN bListenError;\r
+  size_t BytesReceived;\r
+  int CloseStatus;\r
+  nfds_t Entry;\r
+  INTN EntryPrevious;\r
+  int FdCount;\r
+  nfds_t Index;\r
+  socklen_t LengthInBytes;\r
+  struct sockaddr_in RemoteAddress;\r
+  int Socket;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+\r
+  //\r
+  //  Check for control-C\r
+  //\r
+  bListenError = FALSE;\r
+  Status = ControlCCheck ( );\r
+  if ( !EFI_ERROR ( Status )) {\r
+    //\r
+    //  Poll the sockets\r
+    //\r
+    FdCount = poll ( &PollFd[0],\r
+                     MaxPort,\r
+                     0 );\r
+    if ( -1 == FdCount ) {\r
+      //\r
+      //  Poll error\r
+      //\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Poll error, errno: %d\r\n",\r
+                errno ));\r
+      Status = EFI_DEVICE_ERROR;\r
+    }\r
+    else {\r
+      //\r
+      //  Process the poll output\r
+      //\r
+      Index = 0;\r
+      while ( FdCount ) {\r
+        bRemoveSocket = FALSE;\r
+\r
+        //\r
+        //  Account for this descriptor\r
+        //\r
+        if ( 0 != PollFd [ Index ].revents ) {\r
+          FdCount -= 1;\r
+        }\r
+\r
+        //\r
+        //  Check for a broken connection\r
+        //\r
+        if ( 0 != ( PollFd [ Index ].revents & POLLHUP )) {\r
+          bRemoveSocket = TRUE;\r
+          if ( ListenSocket == PollFd [ Index ].fd ) {\r
+            bListenError = TRUE;\r
+            DEBUG (( DEBUG_ERROR,\r
+                      "ERROR - Network closed on listen socket, errno: %d\r\n",\r
+                      errno ));\r
+          }\r
+          else {\r
+            DEBUG (( DEBUG_ERROR,\r
+                      "ERROR - Network closed on socket %d.%d.%d.%d:%d, errno: %d\r\n",\r
+                      Port [ Index ].RemoteAddress.sin_addr.s_addr & 0xff,\r
+                      ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff,\r
+                      ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff,\r
+                      ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff,\r
+                      htons ( Port [ Index ].RemoteAddress.sin_port ),\r
+                      errno ));\r
+\r
+            //\r
+            //  Close the socket\r
+            //\r
+            CloseStatus = close ( PollFd [ Index ].fd );\r
+            if ( 0 == CloseStatus ) {\r
+              bRemoveSocket = TRUE;\r
+              DEBUG (( DEBUG_INFO,\r
+                        "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",\r
+                        PollFd [ Index ].fd,\r
+                        Port [ Index ].RemoteAddress.sin_addr.s_addr & 0xff,\r
+                        ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff,\r
+                        ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff,\r
+                        ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff,\r
+                        htons ( Port [ Index ].RemoteAddress.sin_port )));\r
+            }\r
+            else {\r
+              DEBUG (( DEBUG_ERROR,\r
+                        "ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n",\r
+                        PollFd [ Index ].fd,\r
+                        Port [ Index ].RemoteAddress.sin_addr.s_addr & 0xff,\r
+                        ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff,\r
+                        ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff,\r
+                        ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff,\r
+                        htons ( Port [ Index ].RemoteAddress.sin_port ),\r
+                        errno ));\r
+            }\r
+          }\r
+        }\r
+        \r
+        //\r
+        //  Check for a connection or read data\r
+        //\r
+        if ( 0 != ( PollFd [ Index ].revents & POLLRDNORM )) {\r
+          //\r
+          //  Check for a connection\r
+          //\r
+          if ( ListenSocket == PollFd [ Index ].fd ) {\r
+            //\r
+            //  Another client connection was received\r
+            //\r
+            LengthInBytes = sizeof ( RemoteAddress );\r
+            Socket = accept ( ListenSocket,\r
+                              (struct sockaddr *) &RemoteAddress,\r
+                              &LengthInBytes );\r
+            if ( -1 == Socket ) {\r
+              //\r
+              //  Listen socket error\r
+              //\r
+              bListenError = TRUE;\r
+              bRemoveSocket = TRUE;\r
+              DEBUG (( DEBUG_ERROR,\r
+                        "ERROR - Listen socket failure, errno: %d\r\n",\r
+                        errno ));\r
+            }\r
+            else {\r
+              //\r
+              //  Determine if there is room for this connection\r
+              //\r
+              if (( MAX_CONNECTIONS <= MaxPort )\r
+                || ((( MAX_CONNECTIONS - 1 ) == MaxPort ) && ( -1 == ListenSocket ))) {\r
+                //\r
+                //  Display the connection\r
+                //\r
+                Print ( L"Rejecting connection to remote system %d.%d.%d.%d:%d\r\n",\r
+                        RemoteAddress.sin_addr.s_addr & 0xff,\r
+                        ( RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff,\r
+                        ( RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff,\r
+                        ( RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff,\r
+                        htons ( RemoteAddress.sin_port ));\r
+\r
+                //\r
+                //  No room for this connection\r
+                //  Close the connection\r
+                //\r
+                CloseStatus = close ( Socket );\r
+                if ( 0 == CloseStatus ) {\r
+                  bRemoveSocket = TRUE;\r
+                  DEBUG (( DEBUG_INFO,\r
+                            "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",\r
+                            PollFd [ Index ].fd,\r
+                            RemoteAddress.sin_addr.s_addr & 0xff,\r
+                            ( RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff,\r
+                            ( RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff,\r
+                            ( RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff,\r
+                            htons ( RemoteAddress.sin_port )));\r
+                }\r
+                else {\r
+                  DEBUG (( DEBUG_ERROR,\r
+                            "ERROR - Failed to close socket 0x%08x, errno: %d\r\n",\r
+                            PollFd [ Index ].fd,\r
+                            errno ));\r
+                }\r
+\r
+                //\r
+                //  Keep the application running\r
+                //  No issue with the listen socket\r
+                //\r
+                Status = EFI_SUCCESS;\r
+              }\r
+              else\r
+              {\r
+                //\r
+                //  Display the connection\r
+                //\r
+                Print ( L"Connected to remote system %d.%d.%d.%d:%d\r\n",\r
+                        RemoteAddress.sin_addr.s_addr & 0xff,\r
+                        ( RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff,\r
+                        ( RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff,\r
+                        ( RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff,\r
+                        htons ( RemoteAddress.sin_port ));\r
+\r
+                //\r
+                //  Allocate the client connection\r
+                //\r
+                Index = MaxPort++;\r
+                Port [ Index ].BytesAverage = 0;\r
+                Port [ Index ].BytesPrevious = 0;\r
+                Port [ Index ].BytesTotal = 0;\r
+                Port [ Index ].Samples = 0;\r
+                Port [ Index ].RemoteAddress.sin_len = RemoteAddress.sin_len;\r
+                Port [ Index ].RemoteAddress.sin_family = RemoteAddress.sin_family;\r
+                Port [ Index ].RemoteAddress.sin_port = RemoteAddress.sin_port;\r
+                Port [ Index ].RemoteAddress.sin_addr = RemoteAddress.sin_addr;\r
+                PollFd [ Index ].fd = Socket;\r
+                PollFd [ Index ].events = POLLRDNORM | POLLHUP;\r
+                PollFd [ Index ].revents = 0;\r
+              }\r
+            }\r
+          }\r
+          else {\r
+            //\r
+            //  Data received\r
+            //\r
+            BytesReceived = read ( PollFd [ Index ].fd,\r
+                                   &Buffer,\r
+                                   sizeof ( Buffer ));\r
+            if ( 0 < BytesReceived ) {\r
+              //\r
+              //  Display the amount of data received\r
+              //\r
+              DEBUG (( DEBUG_INFO,\r
+                        "0x%08x: Socket received 0x%08x bytes from %d.%d.%d.%d:%d\r\n",\r
+                        PollFd [ Index ].fd,\r
+                        BytesReceived,\r
+                        Port [ Index ].RemoteAddress.sin_addr.s_addr & 0xff,\r
+                        ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff,\r
+                        ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff,\r
+                        ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff,\r
+                        htons ( Port [ Index ].RemoteAddress.sin_port )));\r
+\r
+              //\r
+              //  Synchronize with the TimerCallback routine\r
+              //\r
+              TplPrevious = gBS->RaiseTPL ( TPL_DATASINK );\r
+\r
+              //\r
+              //  Account for the data received\r
+              //\r
+              Port [ Index ].BytesTotal += BytesReceived;\r
+\r
+              //\r
+              //  Release the synchronization with the TimerCallback routine\r
+              //\r
+              gBS->RestoreTPL ( TplPrevious );\r
+            }\r
+            else if ( -1 == BytesReceived ) {\r
+              //\r
+              //  Close the socket\r
+              //\r
+              DEBUG (( DEBUG_INFO,\r
+                        "ERROR - Receive failure for %d.%d.%d.%d:%d, errno: %d\r\n",\r
+                        Port [ Index ].RemoteAddress.sin_addr.s_addr & 0xff,\r
+                        ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff,\r
+                        ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff,\r
+                        ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff,\r
+                        htons ( Port [ Index ].RemoteAddress.sin_port ),\r
+                        errno ));\r
+              CloseStatus = close ( PollFd [ Index ].fd );\r
+              if ( 0 == CloseStatus ) {\r
+                bRemoveSocket = TRUE;\r
+                DEBUG (( DEBUG_INFO,\r
+                          "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",\r
+                          PollFd [ Index ].fd,\r
+                          Port [ Index ].RemoteAddress.sin_addr.s_addr & 0xff,\r
+                          ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff,\r
+                          ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff,\r
+                          ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff,\r
+                          htons ( Port [ Index ].RemoteAddress.sin_port )));\r
+              }\r
+              else {\r
+                DEBUG (( DEBUG_ERROR,\r
+                          "ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n",\r
+                          PollFd [ Index ].fd,\r
+                          Port [ Index ].RemoteAddress.sin_addr.s_addr & 0xff,\r
+                          ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff,\r
+                          ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff,\r
+                          ( Port [ Index ].RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff,\r
+                          htons ( Port [ Index ].RemoteAddress.sin_port ),\r
+                          errno ));\r
+              }\r
+            }\r
+\r
+            //\r
+            //  Keep the application running\r
+            //  No issue with the listen socket\r
+            //\r
+            Status = EFI_SUCCESS;\r
+          }\r
+        }\r
+\r
+        //\r
+        //  Remove the socket if necessary\r
+        //\r
+        if ( bRemoveSocket ) {\r
+          DEBUG (( DEBUG_INFO,\r
+                    "0x%08x: Socket removed from polling\r\n",\r
+                    PollFd [ Index ].fd ));\r
+          MaxPort -= 1;\r
+          for ( Entry = Index + 1; MaxPort >= Entry; Entry++ ) {\r
+            EntryPrevious = Entry;\r
+            Port [ EntryPrevious ].BytesAverage = Port [ Entry ].BytesAverage;\r
+            Port [ EntryPrevious ].BytesPrevious = Port [ Entry ].BytesPrevious;\r
+            Port [ EntryPrevious ].BytesTotal = Port [ Entry ].BytesTotal;\r
+            Port [ EntryPrevious ].RemoteAddress.sin_len = Port [ Entry ].RemoteAddress.sin_len;\r
+            Port [ EntryPrevious ].RemoteAddress.sin_family = Port [ Entry ].RemoteAddress.sin_family;\r
+            Port [ EntryPrevious ].RemoteAddress.sin_port = Port [ Entry ].RemoteAddress.sin_port;\r
+            Port [ EntryPrevious ].RemoteAddress.sin_addr.s_addr = Port [ Entry ].RemoteAddress.sin_addr.s_addr;\r
+            Port [ EntryPrevious ].Samples = Port [ Entry ].Samples;\r
+            PollFd [ EntryPrevious ].events = PollFd [ Entry ].events;\r
+            PollFd [ EntryPrevious ].fd = PollFd [ Entry ].fd;\r
+            PollFd [ EntryPrevious ].revents = PollFd [ Entry ].revents;\r
+          }\r
+          PollFd [ MaxPort ].fd = -1;\r
+          Index -= 1;\r
+        }\r
+\r
+        //\r
+        //  Account for this socket\r
+        //\r
+        Index += 1;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the listen failure if necessary\r
+  //\r
+  if (( !EFI_ERROR ( Status )) && bListenError ) {\r
+    Status = EFI_NOT_STARTED;\r
+  }\r
+\r
+  //\r
+  //  Return the poll status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Handle the timer callback\r
+\r
+  @param [in] Event     Event that caused this callback\r
+  @param [in] pContext  Context for this routine\r
+**/\r
+VOID\r
+TimerCallback (\r
+  IN EFI_EVENT Event,\r
+  IN VOID * pContext\r
+  )\r
+{\r
+  UINT64 Average;\r
+  UINT64 BytesReceived;\r
+  UINT32 Delta;\r
+  UINT64 DeltaBytes;\r
+  nfds_t Index;\r
+\r
+  //\r
+  //  Notify the other code of the timer tick\r
+  //\r
+  bTick = TRUE;\r
+\r
+  //\r
+  //  Walk the list of ports\r
+  //\r
+  for ( Index = 0; MaxPort > Index; Index++ ) {\r
+    //\r
+    //  Determine if any data was received\r
+    //\r
+    BytesReceived = Port [ Index ].BytesTotal;\r
+    if (( ListenSocket != PollFd [ Index ].fd )\r
+      && ( 0 != BytesReceived )) {\r
+      //\r
+      //  Update the average bytes per second\r
+      //\r
+      DeltaBytes = Port [ Index ].BytesAverage >> AVERAGE_SHIFT_COUNT;\r
+      Port [ Index ].BytesAverage -= DeltaBytes;\r
+      DeltaBytes = BytesReceived - Port [ Index ].BytesPrevious;\r
+      Port [ Index ].BytesPrevious = BytesReceived;\r
+      Port [ Index ].BytesAverage += DeltaBytes;\r
+\r
+      //\r
+      //  Separate the samples\r
+      //\r
+      if (( 2 << AVERAGE_SHIFT_COUNT ) == Port [ Index ].Samples ) {\r
+        Print ( L"---------- Stable average ----------\r\n" );\r
+      }\r
+      Port [ Index ].Samples += 1;\r
+\r
+      //\r
+      //  Display the data rate\r
+      //\r
+      Delta = (UINT32)( DeltaBytes >> DATA_RATE_UPDATE_SHIFT );\r
+      Average = Port [ Index ].BytesAverage >> ( AVERAGE_SHIFT_COUNT + DATA_RATE_UPDATE_SHIFT );\r
+      if ( Average < RANGE_SWITCH ) {\r
+        Print ( L"%d Bytes/sec, Ave: %d Bytes/Sec\r\n",\r
+                Delta,\r
+                (UINT32) Average );\r
+      }\r
+      else {\r
+        Average >>= 10;\r
+        if ( Average < RANGE_SWITCH ) {\r
+          Print ( L"%d Bytes/sec, Ave: %d KiBytes/Sec\r\n",\r
+                  Delta,\r
+                  (UINT32) Average );\r
+        }\r
+        else {\r
+          Average >>= 10;\r
+          if ( Average < RANGE_SWITCH ) {\r
+            Print ( L"%d Bytes/sec, Ave: %d MiBytes/Sec\r\n",\r
+                    Delta,\r
+                    (UINT32) Average );\r
+          }\r
+          else {\r
+            Average >>= 10;\r
+            if ( Average < RANGE_SWITCH ) {\r
+              Print ( L"%d Bytes/sec, Ave: %d GiBytes/Sec\r\n",\r
+                      Delta,\r
+                      (UINT32) Average );\r
+            }\r
+            else {\r
+              Average >>= 10;\r
+              if ( Average < RANGE_SWITCH ) {\r
+                Print ( L"%d Bytes/sec, Ave: %d TiBytes/Sec\r\n",\r
+                        Delta,\r
+                        Average );\r
+              }\r
+              else {\r
+                Average >>= 10;\r
+                Print ( L"%d Bytes/sec, Ave: %d PiBytes/Sec\r\n",\r
+                        Delta,\r
+                        (UINT32) Average );\r
+              }\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Create the timer\r
+\r
+  @retval  EFI_SUCCESS  The timer was successfully created\r
+  @retval  Other        Timer initialization failed\r
+**/\r
+EFI_STATUS\r
+TimerCreate (\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Create the timer\r
+  //\r
+  Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
+                              TPL_DATASINK,\r
+                              TimerCallback,\r
+                              NULL,\r
+                              &pTimer );\r
+  if ( EFI_ERROR ( Status )) {\r
+    DEBUG (( DEBUG_ERROR,\r
+              "ERROR - Failed to allocate the timer event, Status: %r\r\n",\r
+              Status ));\r
+  }\r
+  else {\r
+    DEBUG (( DEBUG_INFO,\r
+              "0x%08x: Timer created\r\n",\r
+              pTimer ));\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Stop the timer\r
+\r
+  @retval  EFI_SUCCESS  The timer was stopped successfully\r
+  @retval  Other        The timer failed to stop\r
+**/\r
+EFI_STATUS\r
+TimerStop (\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Determine if the timer is running\r
+  //\r
+  if ( bTimerRunning ) {\r
+    //\r
+    //  Stop the timer\r
+    //\r
+    Status = gBS->SetTimer ( pTimer,\r
+                             TimerCancel,\r
+                             0 );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to stop the timer, Status: %r\r\n",\r
+                Status ));\r
+    }\r
+    else {\r
+      //\r
+      //  Timer timer is now stopped\r
+      //\r
+      bTimerRunning = FALSE;\r
+      DEBUG (( DEBUG_INFO,\r
+                "0x%08x: Timer stopped\r\n",\r
+                pTimer ));\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Start the timer\r
+\r
+  @param [in] Milliseconds  The number of milliseconds between timer callbacks\r
+\r
+  @retval  EFI_SUCCESS  The timer was successfully created\r
+  @retval  Other        Timer initialization failed\r
+**/\r
+EFI_STATUS\r
+TimerStart (\r
+  UINTN Milliseconds\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  UINT64 TimeDelay;\r
+\r
+  //\r
+  //  Stop the timer if necessary\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  if ( bTimerRunning ) {\r
+    Status = TimerStop ( );\r
+  }\r
+  if ( !EFI_ERROR ( Status )) {\r
+    //\r
+    //  Compute the new delay\r
+    //\r
+    TimeDelay = Milliseconds;\r
+    TimeDelay *= 1000 * 10;\r
+\r
+    //\r
+    //  Start the timer\r
+    //\r
+    Status = gBS->SetTimer ( pTimer,\r
+                             TimerPeriodic,\r
+                             TimeDelay );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to start the timer, Status: %r\r\n",\r
+                Status ));\r
+    }\r
+    else {\r
+      //\r
+      //  The timer is now running\r
+      //\r
+      bTimerRunning = TRUE;\r
+      DEBUG (( DEBUG_INFO,\r
+        "0x%08x: Timer running\r\n",\r
+        pTimer ));\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Destroy the timer\r
+\r
+  @retval  EFI_SUCCESS  The timer was destroyed successfully\r
+  @retval  Other        Failed to destroy the timer\r
+**/\r
+EFI_STATUS\r
+TimerDestroy (\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Determine if the timer is running\r
+  //\r
+  if ( bTimerRunning ) {\r
+    //\r
+    //  Stop the timer\r
+    //\r
+    Status = TimerStop ( );\r
+  }\r
+  if (( !EFI_ERROR ( Status )) && ( NULL != pTimer )) {\r
+    //\r
+    //  Done with this timer\r
+    //\r
+    Status = gBS->CloseEvent ( pTimer );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to free the timer event, Status: %r\r\n",\r
+                Status ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_INFO,\r
+                "0x%08x: Timer Destroyed\r\n",\r
+                pTimer ));\r
+      pTimer = NULL;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Receive data from the DataSource program to test a network's bandwidth.\r
+\r
+  @param [in] Argc  The number of arguments\r
+  @param [in] Argv  The argument value array\r
+\r
+  @retval  0        The application exited normally.\r
+  @retval  Other    An error occurred.\r
+**/\r
+int\r
+main (\r
+  IN int Argc,\r
+  IN char **Argv\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  DEBUG (( DEBUG_INFO,\r
+            "DataSink starting\r\n" ));\r
+\r
+  //\r
+  //  Use for/break instead of goto\r
+  //\r
+  for ( ; ; )\r
+  {\r
+    //\r
+    //  Create the timer\r
+    //\r
+    bTick = TRUE;\r
+    Status = TimerCreate ( );\r
+    if ( EFI_ERROR ( Status )) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Start a timer to perform network polling and display updates\r
+    //\r
+    Status = TimerStart ( 1 * 1000 );\r
+    if ( EFI_ERROR ( Status )) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Loop forever waiting for abuse\r
+    //\r
+    do {\r
+      ListenSocket = -1;\r
+      do {\r
+        //\r
+        //  Complete any client operations\r
+        //\r
+        Status = SocketPoll ( );\r
+        if ( EFI_ERROR ( Status )) {\r
+          //\r
+          //  Control-C\r
+          //\r
+          break;\r
+        }\r
+      \r
+        //\r
+        //  Wait for a while\r
+        //\r
+      } while ( !bTick );\r
+      if ( EFI_ERROR ( Status )) {\r
+        //\r
+        //  Control-C\r
+        //\r
+        break;\r
+      }\r
+      \r
+      //\r
+      //  Wait for the network layer to initialize\r
+      //\r
+      Status = SocketNew ( );\r
+      if ( EFI_ERROR ( Status )) {\r
+        continue;\r
+      }\r
+\r
+      //\r
+      //  Wait for the remote network application to start\r
+      //\r
+      Status = SocketAccept ( );\r
+      if ( EFI_NOT_STARTED == Status ) {\r
+        Status = SocketClose ( );\r
+        continue;\r
+      }\r
+      else if ( EFI_SUCCESS != Status ) {\r
+        //\r
+        //  Control-C\r
+        //\r
+        break;\r
+      }\r
+\r
+      //\r
+      //  Send data until the connection breaks\r
+      //\r
+      do {\r
+        Status = SocketPoll ( );\r
+      } while ( !EFI_ERROR ( Status ));\r
+\r
+      //\r
+      //  Done with the socket\r
+      //\r
+      Status = SocketClose ( );\r
+    } while ( !EFI_ERROR ( Status ));\r
+\r
+    //\r
+    //  Close the socket if necessary\r
+    //\r
+    SocketClose ( );\r
+\r
+    //\r
+    //  All done\r
+    //\r
+    break;\r
+  }\r
+\r
+  //\r
+  //  Stop the timer if necessary\r
+  //\r
+  TimerStop ( );\r
+  TimerDestroy ( );\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DEBUG (( DEBUG_INFO,\r
+            "DataSink exiting, Status: %r\r\n",\r
+            Status ));\r
+  return Status;\r
+}\r
diff --git a/AppPkg/Applications/Sockets/DataSink/DataSink.inf b/AppPkg/Applications/Sockets/DataSink/DataSink.inf
new file mode 100644 (file)
index 0000000..7c79ab2
--- /dev/null
@@ -0,0 +1,67 @@
+#/** @file\r
+#  DataSink Application\r
+#\r
+# This file contains an 'Intel Peripheral Driver' and is      \r
+# licensed for Intel CPUs and chipsets under the terms of your\r
+# license agreement with Intel or your vendor.  This file may \r
+# be modified by the user, subject to additional terms of the \r
+# license agreement                                           \r
+#\r
+#\r
+# Copyright (c)  20011 Intel Corporation. All rights reserved\r
+# This software and associated documentation (if any) is furnished\r
+# under a license and may only be used or copied in accordance\r
+# with the terms of the license. Except as permitted by such\r
+# license, no part of this software or documentation may be\r
+# reproduced, stored in a retrieval system, or transmitted in any\r
+# form or by any means without the express written consent of\r
+# Intel Corporation.\r
+#\r
+##\r
+\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DataSink\r
+  FILE_GUID                      = A85DCA1B-198F-4e14-A673-874264687E85\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = ShellCEntryLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  DataSink.c\r
+\r
+\r
+[Pcd]\r
+  gStdLibTokenSpaceGuid.DataSource_Port\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  StdLib/StdLib.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  BsdSocketLib\r
+  DebugLib\r
+  EfiSocketLib\r
+  LibC\r
+  LibMath\r
+  ShellCEntryLib\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+#  UseSocketDxe\r
+\r
+[BuildOptions]\r
+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186\r
+   MSFT:*_*_*_CC_FLAGS = /Od\r
+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable\r
+\r
diff --git a/AppPkg/Applications/Sockets/DataSource/DataSource.c b/AppPkg/Applications/Sockets/DataSource/DataSource.c
new file mode 100644 (file)
index 0000000..d8f7f05
--- /dev/null
@@ -0,0 +1,1615 @@
+/** @file\r
+  Data source for network testing.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <errno.h>\r
+#include <Uefi.h>\r
+\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <netinet/in.h>\r
+\r
+#include <Protocol/ServiceBinding.h>\r
+#include <Protocol/Tcp4.h>\r
+\r
+#include <sys/EfiSysCall.h>\r
+#include <sys/poll.h>\r
+#include <sys/socket.h>\r
+\r
+\r
+#define RANGE_SWITCH                2048  ///<  Switch display ranges\r
+#define DATA_RATE_UPDATE_SHIFT      2     ///<  2n seconds between updates\r
+#define AVERAGE_SHIFT_COUNT ( 6 - DATA_RATE_UPDATE_SHIFT )  ///<  2n samples in average\r
+\r
+#define TPL_DATASOURCE      TPL_CALLBACK  ///<  Synchronization TPL\r
+\r
+#define PACKET_SIZE                 1448  ///<  Size of data packets\r
+#define DATA_BUFFER_SIZE    (( 65536 / PACKET_SIZE ) * PACKET_SIZE )  ///<  Buffer size in bytes\r
+\r
+\r
+//\r
+//  Socket Data\r
+//\r
+int Socket = -1;\r
+\r
+//\r
+//  TCP V4 Data\r
+//\r
+BOOLEAN bTcp4;                      ///<  TRUE if TCP4 is being used\r
+BOOLEAN bTcp4Connected;             ///<  TRUE if connected to remote system\r
+BOOLEAN bTcp4Connecting;            ///<  TRUE while connection in progress\r
+UINTN Tcp4Index;                    ///<  Index into handle array\r
+EFI_HANDLE Tcp4Controller;          ///<  Network controller handle\r
+EFI_HANDLE Tcp4Handle;              ///<  TCP4 port handle\r
+EFI_TCP4_PROTOCOL * pTcp4Protocol;  ///<  TCP4 protocol pointer\r
+EFI_SERVICE_BINDING_PROTOCOL * pTcp4Service;  ///<  TCP4 Service binding\r
+EFI_TCP4_CONFIG_DATA Tcp4ConfigData;///<  TCP4 configuration data\r
+EFI_TCP4_OPTION Tcp4Option;         ///<  TCP4 port options\r
+EFI_TCP4_CLOSE_TOKEN Tcp4CloseToken;///<  Close control\r
+EFI_TCP4_CONNECTION_TOKEN Tcp4ConnectToken; ///<  Connection control\r
+EFI_TCP4_LISTEN_TOKEN Tcp4ListenToken;      ///<  Listen control\r
+EFI_TCP4_IO_TOKEN Tcp4TxToken;      ///<  Normal data token\r
+\r
+//\r
+//  Timer Data\r
+//\r
+volatile BOOLEAN bTick;\r
+BOOLEAN bTimerRunning;\r
+EFI_EVENT pTimer;\r
+\r
+//\r
+//  Remote IP Address Data\r
+//\r
+struct sockaddr_in RemoteHostAddress;\r
+CHAR8 * pRemoteHost;\r
+\r
+//\r
+//  Traffic Data\r
+//\r
+UINT64 TotalBytesSent;\r
+UINT64 PreviousBytes;\r
+UINT64 AverageBytes;\r
+UINT64 Samples;\r
+UINT8 Buffer [ DATA_BUFFER_SIZE ];\r
+\r
+\r
+//\r
+//  Forward routine declarations\r
+//\r
+EFI_STATUS TimerStart ( UINTN Milliseconds );\r
+\r
+\r
+/**\r
+  Check for control C entered at console\r
+\r
+  @retval  EFI_SUCCESS  Control C not entered\r
+  @retval  EFI_ABORTED  Control C entered\r
+**/\r
+EFI_STATUS\r
+ControlCCheck (\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Assume no user intervention\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Display user stop request\r
+  //\r
+  if ( EFI_ERROR ( Status )) {\r
+    DEBUG (( DEBUG_INFO,\r
+              "User stop request!\r\n" ));\r
+  }\r
+\r
+  //\r
+  //  Return the check status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Get a digit\r
+\r
+  @param [in] pDigit    The address of the next digit\r
+  @param [out] pValue   The address to receive the value\r
+\r
+  @returns  Returns the address of the separator\r
+\r
+**/\r
+CHAR8 *\r
+GetDigit (\r
+  CHAR8 * pDigit,\r
+  UINT32 * pValue\r
+  )\r
+{\r
+  UINT32 Value;\r
+\r
+  //\r
+  //  Walk the digits\r
+  //\r
+  Value = 0;\r
+  while (( '0' <= *pDigit ) && ( '9' >= *pDigit ))\r
+  {\r
+    //\r
+    //  Make room for the new least significant digit\r
+    //\r
+    Value *= 10;\r
+\r
+    //\r
+    //  Convert the digit from ASCII to binary\r
+    //\r
+    Value += *pDigit - '0';\r
+\r
+    //\r
+    //  Set the next digit\r
+    //\r
+    pDigit += 1;\r
+  }\r
+\r
+  //\r
+  //  Return the value\r
+  //\r
+  *pValue = Value;\r
+\r
+  //\r
+  //  Return the next separator\r
+  //\r
+  return pDigit;\r
+}\r
+\r
+\r
+/**\r
+  Get the IP address\r
+\r
+  @retval  EFI_SUCCESS  The IP address is valid\r
+  @retval  Other        Failure to convert the IP address\r
+**/\r
+EFI_STATUS\r
+IpAddress (\r
+  )\r
+{\r
+  CHAR8 * pSeparator;\r
+  INT32 RemoteAddress;\r
+  EFI_STATUS Status;\r
+  UINT32 Value1;\r
+  UINT32 Value2;\r
+  UINT32 Value3;\r
+  UINT32 Value4;\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  Status = EFI_INVALID_PARAMETER;\r
+\r
+  //\r
+  //  Convert the IP address from a string to a numeric value\r
+  //\r
+  pSeparator = GetDigit ( pRemoteHost, &Value1 );\r
+  if (( 255 >= Value1 ) && ( '.' == *pSeparator )) {\r
+    pSeparator = GetDigit ( ++pSeparator, &Value2 );\r
+    if (( 255 >= Value2 ) && ( '.' == *pSeparator )) {\r
+      pSeparator = GetDigit ( ++pSeparator, &Value3 );\r
+      if (( 255 >= Value3 ) && ( '.' == *pSeparator )) {\r
+        pSeparator = GetDigit ( ++pSeparator, &Value4 );\r
+        if (( 255 >= Value4 ) && ( 0 == *pSeparator )) {\r
+          RemoteAddress = Value1\r
+                        | ( Value2 << 8 )\r
+                        | ( Value3 << 16 )\r
+                        | ( Value4 << 24 );\r
+          RemoteHostAddress.sin_addr.s_addr = (UINT32) RemoteAddress;\r
+          Status = EFI_SUCCESS;\r
+          DEBUG (( DEBUG_INFO,\r
+                    "%d.%d.%d.%d: Remote host IP address\r\n",\r
+                    Value1,\r
+                    Value2,\r
+                    Value3,\r
+                    Value4 ));\r
+        }\r
+      }\r
+    }\r
+  }\r
+  if ( EFI_ERROR ( Status )) {\r
+    Print ( L"Invalid digit detected: %d\r\n", *pSeparator );\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Close the socket\r
+\r
+  @retval  EFI_SUCCESS  The application is running normally\r
+  @retval  Other        The user stopped the application\r
+**/\r
+EFI_STATUS\r
+SocketClose (\r
+  )\r
+{\r
+  int CloseStatus;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Determine if the socket is open\r
+  //\r
+  Status = EFI_DEVICE_ERROR;\r
+  if ( -1 != Socket ) {\r
+    //\r
+    //  Attempt to close the socket\r
+    //\r
+    CloseStatus = close ( Socket );\r
+    if ( 0 == CloseStatus ) {\r
+      DEBUG (( DEBUG_INFO,\r
+                "0x%08x: Socket closed\r\n",\r
+                Socket ));\r
+      Socket = -1;\r
+      Status = EFI_SUCCESS;\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR: Failed to close socket, errno: %d\r\n",\r
+                errno ));\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Connect the socket\r
+\r
+  @retval  EFI_SUCCESS  The application is running normally\r
+  @retval  Other        The user stopped the application\r
+**/\r
+EFI_STATUS\r
+SocketConnect (\r
+  )\r
+{\r
+  int ConnectStatus;\r
+  UINT32 RemoteAddress;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Display the connecting message\r
+  //\r
+  RemoteAddress = RemoteHostAddress.sin_addr.s_addr;\r
+  Print ( L"Connecting to remote system %d.%d.%d.%d:%d\r\n",\r
+          RemoteAddress & 0xff,\r
+          ( RemoteAddress >> 8 ) & 0xff,\r
+          ( RemoteAddress >> 16 ) & 0xff,\r
+          ( RemoteAddress >> 24 ) & 0xff,\r
+          htons ( RemoteHostAddress.sin_port ));\r
+\r
+  //\r
+  //  Connect to the remote system\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  do {\r
+    //\r
+    //  Check for user stop request\r
+    //\r
+    while ( ! bTick ) {\r
+      Status = ControlCCheck ( );\r
+      if ( EFI_ERROR ( Status )) {\r
+        break;\r
+      }\r
+    }\r
+    bTick = FALSE;\r
+    if ( EFI_ERROR ( Status )) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Connect to the remote system\r
+    //\r
+    ConnectStatus = connect ( Socket,\r
+                              (struct sockaddr *) &RemoteHostAddress,\r
+                              RemoteHostAddress.sin_len );\r
+    if ( -1 != ConnectStatus ) {\r
+      Print ( L"Connected to remote system %d.%d.%d.%d:%d\r\n",\r
+              RemoteAddress & 0xff,\r
+              ( RemoteAddress >> 8 ) & 0xff,\r
+              ( RemoteAddress >> 16 ) & 0xff,\r
+              ( RemoteAddress >> 24 ) & 0xff,\r
+              htons ( RemoteHostAddress.sin_port ));\r
+    }\r
+    else {\r
+      //\r
+      //  Close the socket and try again\r
+      //\r
+      if ( EAGAIN != errno ) {\r
+        Status = EFI_NOT_STARTED;\r
+        break;\r
+      }\r
+    }\r
+  } while ( -1 == ConnectStatus );\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Create the socket\r
+\r
+  @retval  EFI_SUCCESS  The application is running normally\r
+  @retval  Other        The user stopped the application\r
+**/\r
+EFI_STATUS\r
+SocketNew (\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Loop creating the socket\r
+  //\r
+  DEBUG (( DEBUG_INFO,\r
+            "Creating the socket\r\n" ));\r
+  do {\r
+    //\r
+    //  Check for user stop request\r
+    //\r
+    Status = ControlCCheck ( );\r
+    if ( EFI_ERROR ( Status )) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Attempt to create the socket\r
+    //\r
+    Socket = socket ( AF_INET,\r
+                      SOCK_STREAM,\r
+                      IPPROTO_TCP );\r
+    if ( -1 != Socket ) {\r
+      DEBUG (( DEBUG_INFO,\r
+                "0x%08x: Socket created\r\n",\r
+                Socket ));\r
+      break;\r
+    }\r
+  } while ( -1 == Socket );\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Send data over the socket\r
+\r
+  @retval  EFI_SUCCESS  The application is running normally\r
+  @retval  Other        The user stopped the application\r
+**/\r
+EFI_STATUS\r
+SocketSend (\r
+  )\r
+{\r
+  size_t BytesSent;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+\r
+  //\r
+  //  Restart the timer\r
+  //\r
+  TimerStart ( 1000 << DATA_RATE_UPDATE_SHIFT );\r
+\r
+  //\r
+  //  Loop until the connection breaks or the user stops\r
+  //\r
+  do {\r
+    //\r
+    //  Check for user stop request\r
+    //\r
+    Status = ControlCCheck ( );\r
+    if ( EFI_ERROR ( Status )) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Send some bytes\r
+    //\r
+    BytesSent = write ( Socket, &Buffer[0], sizeof ( Buffer ));\r
+    if ( -1 == BytesSent ) {\r
+      DEBUG (( DEBUG_INFO,\r
+                "ERROR: send failed, errno: %d\r\n",\r
+                errno ));\r
+\r
+      //\r
+      //  Try again\r
+      //\r
+      Status = EFI_SUCCESS;\r
+\r
+//\r
+//  Exit now\r
+//\r
+Status = EFI_NOT_STARTED;\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Synchronize with the TimerCallback routine\r
+    //\r
+    TplPrevious = gBS->RaiseTPL ( TPL_DATASOURCE );\r
+\r
+    //\r
+    //  Account for the data sent\r
+    //\r
+    TotalBytesSent += BytesSent;\r
+\r
+    //\r
+    //  Release the TimerCallback routine synchronization\r
+    //\r
+    gBS->RestoreTPL ( TplPrevious );\r
+  } while ( !EFI_ERROR ( Status ));\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Open the network connection and send the data.\r
+\r
+  @retval EFI_SUCCESS   Continue looping\r
+  @retval other         Stopped by user's Control-C input\r
+\r
+**/\r
+EFI_STATUS\r
+SocketOpen (\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Use do/while and break instead of goto\r
+  //\r
+  do\r
+  {\r
+    //\r
+    //  Wait for the network layer to initialize\r
+    //\r
+    Status = SocketNew ( );\r
+    if ( EFI_ERROR ( Status )) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Wait for the remote network application to start\r
+    //\r
+    Status = SocketConnect ( );\r
+    if ( EFI_NOT_STARTED == Status ) {\r
+      Status = SocketClose ( );\r
+      continue;\r
+    }\r
+    else if ( EFI_SUCCESS != Status ) {\r
+      //\r
+      //  Control-C\r
+      //\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Send data until the connection breaks\r
+    //\r
+    Status = SocketSend ( );\r
+    if ( EFI_ERROR ( Status )) {\r
+      break;\r
+    }\r
+  } while ( FALSE );\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Close the TCP connection\r
+\r
+  @retval  EFI_SUCCESS  The application is running normally\r
+  @retval  Other        The user stopped the application\r
+**/\r
+EFI_STATUS\r
+Tcp4Close (\r
+  )\r
+{\r
+  UINTN Index;\r
+  UINT8 * pIpAddress;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Close the port\r
+  //\r
+  if ( bTcp4Connected ) {\r
+    Tcp4CloseToken.AbortOnClose = TRUE;\r
+    Status = pTcp4Protocol->Close ( pTcp4Protocol,\r
+                                    &Tcp4CloseToken );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to start the TCP port close, Status: %r\r\n",\r
+                Status ));\r
+    }\r
+    else {\r
+      Status = gBS->WaitForEvent ( 1,\r
+                                   &Tcp4CloseToken.CompletionToken.Event,\r
+                                    &Index );\r
+      if ( EFI_ERROR ( Status )) {\r
+        DEBUG (( DEBUG_ERROR,\r
+                  "ERROR - Failed to wait for close event, Status: %r\r\n",\r
+                  Status ));\r
+      }\r
+      else {\r
+        Status = Tcp4CloseToken.CompletionToken.Status;\r
+        if ( EFI_ERROR ( Status )) {\r
+          DEBUG (( DEBUG_ERROR,\r
+                    "ERROR - Failed to close the TCP port, Status: %r\r\n",\r
+                    Status ));\r
+        }\r
+        else {\r
+          DEBUG (( DEBUG_INFO,\r
+                    "0x%08x: TCP port closed\r\n",\r
+                    pTcp4Protocol ));\r
+          bTcp4Connected = FALSE;\r
+\r
+          //\r
+          //  Display the port closed message\r
+          //\r
+          pIpAddress = (UINT8 *)&RemoteHostAddress.sin_addr.s_addr;\r
+          Print ( L"Closed connection to %d.%d.%d.%d:%d\r\n",\r
+                  pIpAddress[0],\r
+                  pIpAddress[1],\r
+                  pIpAddress[2],\r
+                  pIpAddress[3],\r
+                  htons ( RemoteHostAddress.sin_port ));\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Release the events\r
+  //\r
+  if ( NULL != Tcp4TxToken.CompletionToken.Event ) {\r
+    Status = gBS->CloseEvent ( Tcp4TxToken.CompletionToken.Event );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_INFO,\r
+                "0x%08x: TX event closed\r\n",\r
+                Tcp4TxToken.CompletionToken.Event ));\r
+      Tcp4TxToken.CompletionToken.Event = NULL;\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to close the Tcp4TxToken event, Status: %r\r\n",\r
+                Status ));\r
+    }\r
+  }\r
+\r
+  if ( NULL != Tcp4ListenToken.CompletionToken.Event ) {\r
+    Status = gBS->CloseEvent ( Tcp4ListenToken.CompletionToken.Event );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_INFO,\r
+                "0x%08x: Listen event closed\r\n",\r
+                Tcp4ListenToken.CompletionToken.Event ));\r
+      Tcp4ListenToken.CompletionToken.Event = NULL;\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to close the Tcp4ListenToken event, Status: %r\r\n",\r
+                Status ));\r
+    }\r
+  }\r
+\r
+  if ( NULL != Tcp4ConnectToken.CompletionToken.Event ) {\r
+    Status = gBS->CloseEvent ( Tcp4ConnectToken.CompletionToken.Event );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_INFO,\r
+                "0x%08x: Connect event closed\r\n",\r
+                Tcp4ConnectToken.CompletionToken.Event ));\r
+      Tcp4ConnectToken.CompletionToken.Event = NULL;\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to close the Tcp4ConnectToken event, Status: %r\r\n",\r
+                Status ));\r
+    }\r
+  }\r
+\r
+  if ( NULL != Tcp4CloseToken.CompletionToken.Event ) {\r
+    Status = gBS->CloseEvent ( Tcp4CloseToken.CompletionToken.Event );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_INFO,\r
+                "0x%08x: Close event closed\r\n",\r
+                Tcp4CloseToken.CompletionToken.Event ));\r
+      Tcp4CloseToken.CompletionToken.Event = NULL;\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to close the Tcp4CloseToken event, Status: %r\r\n",\r
+                Status ));\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Close the TCP protocol\r
+  //\r
+  if ( NULL != pTcp4Protocol ) {\r
+    Status = gBS->CloseProtocol ( Tcp4Handle,\r
+                                  &gEfiTcp4ProtocolGuid,\r
+                                  gImageHandle,\r
+                                  NULL );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to close the TCP protocol, Status: %r\r\n",\r
+                Status ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_INFO,\r
+                "0x%08x: TCP4 protocol closed\r\n",\r
+                pTcp4Protocol ));\r
+      pTcp4Protocol = NULL;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Done with the TCP service\r
+  //\r
+  if ( NULL != Tcp4Handle ) {\r
+    Status = pTcp4Service->DestroyChild ( pTcp4Service,\r
+                                          Tcp4Handle );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to release TCP service handle, Status: %r\r\n",\r
+                Status ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_INFO,\r
+                "Ox%08x: TCP service closed\r\n",\r
+                Tcp4Handle ));\r
+      Tcp4Handle = NULL;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Close the service protocol\r
+  //\r
+  if ( NULL != pTcp4Service ) {\r
+    Status = gBS->CloseProtocol ( Tcp4Controller,\r
+                                  &gEfiTcp4ServiceBindingProtocolGuid,\r
+                                  gImageHandle,\r
+                                  NULL );\r
+    if ( !EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_INFO,\r
+                "0x%08x: Controller closed gEfiTcp4ServiceBindingProtocolGuid protocol\r\n",\r
+                Tcp4Controller ));\r
+      pTcp4Service = NULL;\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to close the gEfiTcp4ServiceBindingProtocolGuid protocol, Status: %r\r\n",\r
+                Status ));\r
+    }\r
+  }\r
+  Tcp4Controller = NULL;\r
+  bTcp4Connecting = TRUE;\r
+\r
+  //\r
+  //  Mark the connection as closed\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Locate TCP protocol\r
+\r
+  @retval EFI_SUCCESS   Protocol found\r
+  @retval other         Protocl not found\r
+**/\r
+EFI_STATUS\r
+Tcp4Locate (\r
+  )\r
+{\r
+  UINTN HandleCount;\r
+  EFI_HANDLE * pHandles;\r
+  UINT8 * pIpAddress;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Use do/while and break instead of goto\r
+  //\r
+  do {\r
+    //\r
+    //  Attempt to locate the next TCP adapter in the system\r
+    //\r
+    Status = gBS->LocateHandleBuffer ( ByProtocol,\r
+                                       &gEfiTcp4ServiceBindingProtocolGuid,\r
+                                       NULL,\r
+                                       &HandleCount,\r
+                                       &pHandles );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_WARN,\r
+                "WARNING - No network controllers or TCP4 available, Status: %r\r\n",\r
+                Status ));\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Wrap the index if necessary\r
+    //\r
+    if ( HandleCount <= Tcp4Index ) {\r
+      Tcp4Index = 0;\r
+    \r
+      //\r
+      //  Wait for the next timer tick\r
+      //\r
+      do {\r
+      } while ( !bTick );\r
+      bTick = FALSE;\r
+    }\r
+\r
+    //\r
+    //  Display the connecting message\r
+    //\r
+    if ( bTcp4Connecting ) {\r
+      pIpAddress = (UINT8 *)&RemoteHostAddress.sin_addr.s_addr;\r
+      Print ( L"Connecting to %d.%d.%d.%d:%d\r\n",\r
+              pIpAddress[0],\r
+              pIpAddress[1],\r
+              pIpAddress[2],\r
+              pIpAddress[3],\r
+              htons ( RemoteHostAddress.sin_port ));\r
+      bTcp4Connecting = FALSE;\r
+    }\r
+    \r
+    //\r
+    //  Open the network controller's service protocol\r
+    //\r
+    Tcp4Controller = pHandles [ Tcp4Index++ ];\r
+    Status = gBS->OpenProtocol (\r
+                    Tcp4Controller,\r
+                    &gEfiTcp4ServiceBindingProtocolGuid,\r
+                    (VOID **) &pTcp4Service,\r
+                    gImageHandle,\r
+                    NULL,\r
+                    EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to open gEfiTcp4ServiceBindingProtocolGuid on controller 0x%08x\r\n",\r
+                Tcp4Controller ));\r
+      Tcp4Controller = NULL;\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_INFO,\r
+              "0x%08x: Controller opened gEfiTcp4ServiceBindingProtocolGuid protocol\r\n",\r
+              Tcp4Controller ));\r
+\r
+    //\r
+    //  Connect to the TCP service\r
+    //\r
+    Status = pTcp4Service->CreateChild ( pTcp4Service,\r
+                                         &Tcp4Handle );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to open TCP service, Status: %r\r\n",\r
+                Status ));\r
+      Tcp4Handle = NULL;\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_INFO,\r
+              "Ox%08x: TCP service opened\r\n",\r
+              Tcp4Handle ));\r
+\r
+    //\r
+    //  Locate the TCP protcol\r
+    //\r
+    Status = gBS->OpenProtocol ( Tcp4Handle,\r
+                                 &gEfiTcp4ProtocolGuid,\r
+                                 (VOID **)&pTcp4Protocol,\r
+                                 gImageHandle,\r
+                                 NULL,\r
+                                 EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to open the TCP protocol, Status: %r\r\n",\r
+                Status ));\r
+      pTcp4Protocol = NULL;\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_INFO,\r
+              "0x%08x: TCP4 protocol opened\r\n",\r
+              pTcp4Protocol ));\r
+  }while ( FALSE );\r
+\r
+  //\r
+  //  Release the handle buffer\r
+  //\r
+  gBS->FreePool ( pHandles );\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Send data over the TCP4 connection\r
+\r
+  @retval  EFI_SUCCESS  The application is running normally\r
+  @retval  Other        The user stopped the application\r
+**/\r
+EFI_STATUS\r
+Tcp4Send (\r
+  )\r
+{\r
+  UINTN Index;\r
+  EFI_TCP4_TRANSMIT_DATA Packet;\r
+  EFI_STATUS Status;\r
+  EFI_TPL TplPrevious;\r
+\r
+  //\r
+  //  Restart the timer\r
+  //\r
+  TimerStart ( 1000 << DATA_RATE_UPDATE_SHIFT );\r
+\r
+  //\r
+  //  Initialize the packet\r
+  //\r
+  Packet.DataLength = sizeof ( Buffer );\r
+  Packet.FragmentCount = 1;\r
+  Packet.Push = FALSE;\r
+  Packet.Urgent = FALSE;\r
+  Packet.FragmentTable[0].FragmentBuffer = &Buffer[0];\r
+  Packet.FragmentTable[0].FragmentLength = sizeof ( Buffer );\r
+  Tcp4TxToken.Packet.TxData = &Packet;\r
+\r
+  //\r
+  //  Loop until the connection breaks or the user stops\r
+  //\r
+  do {\r
+    //\r
+    //  Check for user stop request\r
+    //\r
+    Status = ControlCCheck ( );\r
+    if ( EFI_ERROR ( Status )) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Send some bytes\r
+    //\r
+    Status = pTcp4Protocol->Transmit ( pTcp4Protocol,\r
+                                       &Tcp4TxToken );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to start the transmit, Status: %r\r\n",\r
+                Status ));\r
+\r
+      //\r
+      //  Try again\r
+      //\r
+      Status = EFI_SUCCESS;\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Wait for the transmit to complete\r
+    //\r
+    Status = gBS->WaitForEvent ( 1,\r
+                                 &Tcp4TxToken.CompletionToken.Event,\r
+                                 &Index );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to wait for transmit completion, Status: %r\r\n",\r
+                Status ));\r
+\r
+      //\r
+      //  Try again\r
+      //\r
+      Status = EFI_SUCCESS;\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Get the transmit status\r
+    //\r
+    Status = Tcp4TxToken.CompletionToken.Status;\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_WARN,\r
+                "WARNING - Failed the transmission, Status: %r\r\n",\r
+                Status ));\r
+\r
+      //\r
+      //  Try again\r
+      //\r
+      Status = EFI_SUCCESS;\r
+\r
+//\r
+//  Exit now\r
+//\r
+Status = EFI_NOT_STARTED;\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Synchronize with the TimerCallback routine\r
+    //\r
+    TplPrevious = gBS->RaiseTPL ( TPL_DATASOURCE );\r
+\r
+    //\r
+    //  Account for the data sent\r
+    //\r
+    TotalBytesSent += Packet.DataLength;\r
+\r
+    //\r
+    //  Release the TimerCallback routine synchronization\r
+    //\r
+    gBS->RestoreTPL ( TplPrevious );\r
+  } while ( !EFI_ERROR ( Status ));\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Open the network connection and send the data.\r
+\r
+  @retval EFI_SUCCESS   Continue looping\r
+  @retval other         Stopped by user's Control-C input\r
+\r
+**/\r
+EFI_STATUS\r
+Tcp4Open (\r
+  )\r
+{\r
+  UINTN Index;\r
+  UINT8 * pIpAddress;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Use do/while and break instead of goto\r
+  //\r
+  do {\r
+    //\r
+    //  Locate the TCP protocol\r
+    //\r
+    Status = Tcp4Locate ( );\r
+    if ( EFI_ERROR ( Status )) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Create the necessary events\r
+    //\r
+    Status = gBS->CreateEvent ( 0,\r
+                                TPL_CALLBACK,\r
+                                NULL,\r
+                                NULL,\r
+                                &Tcp4CloseToken.CompletionToken.Event );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to create the close event, Status: %r\r\n",\r
+                Status ));\r
+      Tcp4CloseToken.CompletionToken.Event = NULL;\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_INFO,\r
+              "0x%08x: Close event open\r\n",\r
+              Tcp4CloseToken.CompletionToken.Event ));\r
+\r
+    Status = gBS->CreateEvent ( 0,\r
+                                TPL_CALLBACK,\r
+                                NULL,\r
+                                NULL,\r
+                                &Tcp4ConnectToken.CompletionToken.Event );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to create the connect event, Status: %r\r\n",\r
+                Status ));\r
+      Tcp4ConnectToken.CompletionToken.Event = NULL;\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_INFO,\r
+              "0x%08x: Connect event open\r\n",\r
+              Tcp4ConnectToken.CompletionToken.Event ));\r
+\r
+    Status = gBS->CreateEvent ( 0,\r
+                                TPL_CALLBACK,\r
+                                NULL,\r
+                                NULL,\r
+                                &Tcp4ListenToken.CompletionToken.Event );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to create the listen event, Status: %r\r\n",\r
+                Status ));\r
+      Tcp4ListenToken.CompletionToken.Event = NULL;\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_INFO,\r
+              "0x%08x: Listen event open\r\n",\r
+              Tcp4ListenToken.CompletionToken.Event ));\r
+\r
+    Status = gBS->CreateEvent ( 0,\r
+                                TPL_CALLBACK,\r
+                                NULL,\r
+                                NULL,\r
+                                &Tcp4TxToken.CompletionToken.Event );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to create the TX event, Status: %r\r\n",\r
+                Status ));\r
+      Tcp4TxToken.CompletionToken.Event = NULL;\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_INFO,\r
+              "0x%08x: TX event open\r\n",\r
+              Tcp4TxToken.CompletionToken.Event ));\r
+\r
+    //\r
+    //  Configure the local TCP port\r
+    //\r
+    Tcp4ConfigData.TimeToLive = 255;\r
+    Tcp4ConfigData.TypeOfService = 0;\r
+    Tcp4ConfigData.ControlOption = NULL;\r
+    Tcp4ConfigData.AccessPoint.ActiveFlag = TRUE;\r
+    Tcp4ConfigData.AccessPoint.StationAddress.Addr[0] = 0;\r
+    Tcp4ConfigData.AccessPoint.StationAddress.Addr[1] = 0;\r
+    Tcp4ConfigData.AccessPoint.StationAddress.Addr[2] = 0;\r
+    Tcp4ConfigData.AccessPoint.StationAddress.Addr[3] = 0;\r
+    Tcp4ConfigData.AccessPoint.StationPort = 0;\r
+    Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[0] = (UINT8)  RemoteHostAddress.sin_addr.s_addr;\r
+    Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[1] = (UINT8)( RemoteHostAddress.sin_addr.s_addr >> 8 );\r
+    Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[2] = (UINT8)( RemoteHostAddress.sin_addr.s_addr >> 16 );\r
+    Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[3] = (UINT8)( RemoteHostAddress.sin_addr.s_addr >> 24 );\r
+    Tcp4ConfigData.AccessPoint.RemotePort = RemoteHostAddress.sin_port;\r
+    Tcp4ConfigData.AccessPoint.UseDefaultAddress = TRUE;\r
+    Tcp4ConfigData.AccessPoint.SubnetMask.Addr[0] = 0;\r
+    Tcp4ConfigData.AccessPoint.SubnetMask.Addr[1] = 0;\r
+    Tcp4ConfigData.AccessPoint.SubnetMask.Addr[2] = 0;\r
+    Tcp4ConfigData.AccessPoint.SubnetMask.Addr[3] = 0;\r
+    Status = pTcp4Protocol->Configure ( pTcp4Protocol,\r
+                                        &Tcp4ConfigData );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR, \r
+                "ERROR - Failed to configure TCP port, Status: %r\r\n",\r
+                Status ));\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_INFO,\r
+              "0x%08x: TCP4 port configured\r\n",\r
+              pTcp4Protocol ));\r
+\r
+    //\r
+    //  Connect to the remote TCP port\r
+    //\r
+    Status = pTcp4Protocol->Connect ( pTcp4Protocol,\r
+                                      &Tcp4ConnectToken );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to start the connection to the remote system, Status: %r\r\n",\r
+                Status ));\r
+      break;\r
+    }\r
+    Status = gBS->WaitForEvent ( 1,\r
+                                 &Tcp4ConnectToken.CompletionToken.Event,\r
+                                 &Index );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to wait for the connection, Status: %r\r\n",\r
+                Status ));\r
+      break;\r
+    }\r
+    Status = Tcp4ConnectToken.CompletionToken.Status;\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_WARN,\r
+                "WARNING - Failed to connect to the remote system, Status: %r\r\n",\r
+                Status ));\r
+      break;\r
+    }\r
+    DEBUG (( DEBUG_INFO,\r
+              "0x%08x: TCP4 port connected\r\n",\r
+              pTcp4Protocol ));\r
+    bTcp4Connected = TRUE;\r
+\r
+    //\r
+    //  Display the connection\r
+    //\r
+    pIpAddress = (UINT8 *)&RemoteHostAddress.sin_addr.s_addr;\r
+    Print ( L"Connected to %d.%d.%d.%d:%d\r\n",\r
+            pIpAddress[0],\r
+            pIpAddress[1],\r
+            pIpAddress[2],\r
+            pIpAddress[3],\r
+            htons ( RemoteHostAddress.sin_port ));\r
+  } while ( 0 );\r
+\r
+  if ( EFI_ERROR ( Status )) {\r
+    //\r
+    //  Try again\r
+    //\r
+    Status = EFI_SUCCESS;\r
+  }\r
+  else {\r
+    //\r
+    //  Semd data until the connection breaks\r
+    //\r
+    Status = Tcp4Send ( );\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Handle the timer callback\r
+\r
+  @param [in] Event     Event that caused this callback\r
+  @param [in] pContext  Context for this routine\r
+**/\r
+VOID\r
+TimerCallback (\r
+  IN EFI_EVENT Event,\r
+  IN VOID * pContext\r
+  )\r
+{\r
+  UINT64 BytesSent;\r
+  UINT64 DeltaBytes;\r
+  UINT32 Delta;\r
+  UINT64 Average;\r
+\r
+  //\r
+  //  Notify the other code of the timer tick\r
+  //\r
+  bTick = TRUE;\r
+\r
+  //\r
+  //  Update the average bytes per second\r
+  //\r
+  BytesSent = TotalBytesSent;\r
+  if ( 0 != BytesSent ) {\r
+    DeltaBytes = AverageBytes >> AVERAGE_SHIFT_COUNT;\r
+    AverageBytes -= DeltaBytes;\r
+    DeltaBytes = BytesSent - PreviousBytes;\r
+    PreviousBytes = BytesSent;\r
+    AverageBytes += DeltaBytes;\r
+\r
+    //\r
+    //  Separate the samples\r
+    //\r
+    if (( 2 << AVERAGE_SHIFT_COUNT ) == Samples ) {\r
+      Print ( L"---------- Stable average ----------\r\n" );\r
+    }\r
+    Samples += 1;\r
+\r
+    //\r
+    //  Display the data rate\r
+    //\r
+    Delta = (UINT32)( DeltaBytes >> DATA_RATE_UPDATE_SHIFT );\r
+    Average = AverageBytes >> ( AVERAGE_SHIFT_COUNT + DATA_RATE_UPDATE_SHIFT );\r
+    if ( Average < RANGE_SWITCH ) {\r
+      Print ( L"%d Bytes/sec, Ave: %d Bytes/Sec\r\n",\r
+              Delta,\r
+              (UINT32) Average );\r
+    }\r
+    else {\r
+      Average >>= 10;\r
+      if ( Average < RANGE_SWITCH ) {\r
+        Print ( L"%d Bytes/sec, Ave: %d KiBytes/Sec\r\n",\r
+                Delta,\r
+                (UINT32) Average );\r
+      }\r
+      else {\r
+        Average >>= 10;\r
+        if ( Average < RANGE_SWITCH ) {\r
+          Print ( L"%d Bytes/sec, Ave: %d MiBytes/Sec\r\n",\r
+                  Delta,\r
+                  (UINT32) Average );\r
+        }\r
+        else {\r
+          Average >>= 10;\r
+          if ( Average < RANGE_SWITCH ) {\r
+            Print ( L"%d Bytes/sec, Ave: %d GiBytes/Sec\r\n",\r
+                    Delta,\r
+                    (UINT32) Average );\r
+          }\r
+          else {\r
+            Average >>= 10;\r
+            if ( Average < RANGE_SWITCH ) {\r
+              Print ( L"%d Bytes/sec, Ave: %d TiBytes/Sec\r\n",\r
+                      Delta,\r
+                      Average );\r
+            }\r
+            else {\r
+              Average >>= 10;\r
+              Print ( L"%d Bytes/sec, Ave: %d PiBytes/Sec\r\n",\r
+                      Delta,\r
+                      (UINT32) Average );\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Create the timer\r
+\r
+  @retval  EFI_SUCCESS  The timer was successfully created\r
+  @retval  Other        Timer initialization failed\r
+**/\r
+EFI_STATUS\r
+TimerCreate (\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Create the timer\r
+  //\r
+  Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
+                              TPL_DATASOURCE,\r
+                              TimerCallback,\r
+                              NULL,\r
+                              &pTimer );\r
+  if ( EFI_ERROR ( Status )) {\r
+    DEBUG (( DEBUG_ERROR,\r
+              "ERROR - Failed to allocate the timer event, Status: %r\r\n",\r
+              Status ));\r
+  }\r
+  else {\r
+    DEBUG (( DEBUG_INFO,\r
+              "0x%08x: Timer created\r\n",\r
+              pTimer ));\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Stop the timer\r
+\r
+  @retval  EFI_SUCCESS  The timer was stopped successfully\r
+  @retval  Other        The timer failed to stop\r
+**/\r
+EFI_STATUS\r
+TimerStop (\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Determine if the timer is running\r
+  //\r
+  if ( bTimerRunning ) {\r
+    //\r
+    //  Stop the timer\r
+    //\r
+    Status = gBS->SetTimer ( pTimer,\r
+                             TimerCancel,\r
+                             0 );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to stop the timer, Status: %r\r\n",\r
+                Status ));\r
+    }\r
+    else {\r
+      //\r
+      //  Timer timer is now stopped\r
+      //\r
+      bTimerRunning = FALSE;\r
+      DEBUG (( DEBUG_INFO,\r
+                "0x%08x: Timer stopped\r\n",\r
+                pTimer ));\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Start the timer\r
+\r
+  @param [in] Milliseconds  The number of milliseconds between timer callbacks\r
+\r
+  @retval  EFI_SUCCESS  The timer was successfully created\r
+  @retval  Other        Timer initialization failed\r
+**/\r
+EFI_STATUS\r
+TimerStart (\r
+  UINTN Milliseconds\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  UINT64 TimeDelay;\r
+\r
+  //\r
+  //  Stop the timer if necessary\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  if ( bTimerRunning ) {\r
+    Status = TimerStop ( );\r
+  }\r
+  if ( !EFI_ERROR ( Status )) {\r
+    //\r
+    //  Compute the new delay\r
+    //\r
+    TimeDelay = Milliseconds;\r
+    TimeDelay *= 1000 * 10;\r
+\r
+    //\r
+    //  Start the timer\r
+    //\r
+    Status = gBS->SetTimer ( pTimer,\r
+                             TimerPeriodic,\r
+                             TimeDelay );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to start the timer, Status: %r\r\n",\r
+                Status ));\r
+    }\r
+    else {\r
+      //\r
+      //  The timer is now running\r
+      //\r
+      bTimerRunning = TRUE;\r
+      DEBUG (( DEBUG_INFO,\r
+        "0x%08x: Timer running\r\n",\r
+        pTimer ));\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Destroy the timer\r
+\r
+  @retval  EFI_SUCCESS  The timer was destroyed successfully\r
+  @retval  Other        Failed to destroy the timer\r
+**/\r
+EFI_STATUS\r
+TimerDestroy (\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  //  Assume success\r
+  //\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  //  Determine if the timer is running\r
+  //\r
+  if ( bTimerRunning ) {\r
+    //\r
+    //  Stop the timer\r
+    //\r
+    Status = TimerStop ( );\r
+  }\r
+  if (( !EFI_ERROR ( Status )) && ( NULL != pTimer )) {\r
+    //\r
+    //  Done with this timer\r
+    //\r
+    Status = gBS->CloseEvent ( pTimer );\r
+    if ( EFI_ERROR ( Status )) {\r
+      DEBUG (( DEBUG_ERROR,\r
+                "ERROR - Failed to free the timer event, Status: %r\r\n",\r
+                Status ));\r
+    }\r
+    else {\r
+      DEBUG (( DEBUG_INFO,\r
+                "0x%08x: Timer Destroyed\r\n",\r
+                pTimer ));\r
+      pTimer = NULL;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Send data to the DataSink program to test a network's bandwidth.\r
+\r
+  @param [in] Argc  The number of arguments\r
+  @param [in] Argv  The argument value array\r
+\r
+  @retval  0        The application exited normally.\r
+  @retval  Other    An error occurred.\r
+**/\r
+int\r
+main (\r
+  IN int Argc,\r
+  IN char **Argv\r
+  )\r
+{\r
+  EFI_STATUS (* pClose) ();\r
+  EFI_STATUS (* pOpen) ();\r
+  EFI_STATUS Status;\r
+\r
+  DEBUG (( DEBUG_INFO,\r
+            "DataSource starting\r\n" ));\r
+\r
+  //\r
+  //  Validate the command line\r
+  //\r
+  if ( 2 != Argc ) {\r
+    Print ( L"%s  <remote IP address>\r\n", Argv[0] );\r
+    return -1;\r
+  }\r
+\r
+bTcp4 = TRUE;\r
+\r
+  //\r
+  //  Determine the support routines\r
+  //\r
+  if ( bTcp4 ) {\r
+    pOpen = Tcp4Open;\r
+    pClose = Tcp4Close;\r
+    bTcp4Connecting = TRUE;\r
+  }\r
+  else {\r
+    pOpen = SocketOpen;\r
+    pClose = SocketClose;\r
+  }\r
+\r
+  //\r
+  //  Use for/break instead of goto\r
+  //\r
+  for ( ; ; )\r
+  {\r
+    //\r
+    //  No bytes sent so far\r
+    //\r
+    TotalBytesSent = 0;\r
+    AverageBytes = 0;\r
+    PreviousBytes = 0;\r
+    Samples = 0;\r
+\r
+    //\r
+    //  Get the port number\r
+    //\r
+    ZeroMem ( &RemoteHostAddress, sizeof ( RemoteHostAddress ));\r
+    RemoteHostAddress.sin_len = sizeof ( RemoteHostAddress );\r
+    RemoteHostAddress.sin_family = AF_INET;\r
+    RemoteHostAddress.sin_port = htons ( PcdGet16 ( DataSource_Port ));\r
+\r
+Print ( L"Argc: %d\r\n", Argc);\r
+Print ( L"Argv[0]: %a\r\n", Argv[0]);\r
+Print ( L"Argv[1]: %a\r\n", Argv[1]);\r
+\r
+    //\r
+    //  Get the IP address\r
+    //\r
+    pRemoteHost = Argv [1];\r
+    Status = IpAddress ( );\r
+    if ( EFI_ERROR ( Status )) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Create the timer\r
+    //\r
+    bTick = TRUE;\r
+    Status = TimerCreate ( );\r
+    if ( EFI_ERROR ( Status )) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    //  Loop forever abusing the specified system\r
+    //\r
+    do {\r
+      //\r
+      //  Start a timer to perform connection polling and display updates\r
+      //\r
+      Status = TimerStart ( 2 * 1000 );\r
+      if ( EFI_ERROR ( Status )) {\r
+        break;\r
+      }\r
+\r
+      //\r
+      //  Open the network connection and send the data\r
+      //\r
+      Status = pOpen ( );\r
+      if ( EFI_ERROR ( Status )) {\r
+        break;\r
+      }\r
+\r
+      //\r
+      //  Done with the network connection\r
+      //\r
+      Status = pClose ( );\r
+    } while ( !EFI_ERROR ( Status ));\r
+\r
+    //\r
+    //  Close the network connection if necessary\r
+    //\r
+    pClose ( );\r
+\r
+    //\r
+    //  All done\r
+    //\r
+    break;\r
+  }\r
+\r
+  //\r
+  //  Stop the timer if necessary\r
+  //\r
+  TimerStop ( );\r
+  TimerDestroy ( );\r
+\r
+  //\r
+  //  Return the operation status\r
+  //\r
+  DEBUG (( DEBUG_INFO,\r
+            "DataSource exiting, Status: %r\r\n",\r
+            Status ));\r
+  return Status;\r
+}\r
diff --git a/AppPkg/Applications/Sockets/DataSource/DataSource.inf b/AppPkg/Applications/Sockets/DataSource/DataSource.inf
new file mode 100644 (file)
index 0000000..ec9cf6c
--- /dev/null
@@ -0,0 +1,70 @@
+#/** @file\r
+#  DataSource Application\r
+#\r
+# This file contains an 'Intel Peripheral Driver' and is      \r
+# licensed for Intel CPUs and chipsets under the terms of your\r
+# license agreement with Intel or your vendor.  This file may \r
+# be modified by the user, subject to additional terms of the \r
+# license agreement                                           \r
+#\r
+#\r
+# Copyright (c)  20011 Intel Corporation. All rights reserved\r
+# This software and associated documentation (if any) is furnished\r
+# under a license and may only be used or copied in accordance\r
+# with the terms of the license. Except as permitted by such\r
+# license, no part of this software or documentation may be\r
+# reproduced, stored in a retrieval system, or transmitted in any\r
+# form or by any means without the express written consent of\r
+# Intel Corporation.\r
+#\r
+##\r
+\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DataSource\r
+  FILE_GUID                      = 30EB0F26-FC0A-4fd2-B9C9-751EA2BB1980\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = ShellCEntryLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  DataSource.c\r
+\r
+\r
+[Pcd]\r
+  gStdLibTokenSpaceGuid.DataSource_Port\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  StdLib/StdLib.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  BsdSocketLib\r
+  EfiSocketLib\r
+  DebugLib\r
+  LibC\r
+  ShellCEntryLib\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+#  UseSocketDxe\r
+\r
+[Protocols]\r
+  gEfiTcp4ProtocolGuid\r
+  gEfiTcp4ServiceBindingProtocolGuid\r
+\r
+[BuildOptions]\r
+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186\r
+   MSFT:*_*_*_CC_FLAGS = /Od\r
+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable\r
+\r
diff --git a/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.c b/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.c
new file mode 100644 (file)
index 0000000..2e62639
--- /dev/null
@@ -0,0 +1,133 @@
+/** @file\r
+  Translate the port number into a service name\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <errno.h>\r
+#include <netdb.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <Uefi.h>\r
+#include <unistd.h>\r
+\r
+#include <arpa\nameser.h>\r
+#include <arpa\nameser_compat.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <sys/socket.h>\r
+\r
+/**\r
+  Translate the IP address into a host name\r
+\r
+  @param [in] Argc  The number of arguments\r
+  @param [in] Argv  The argument value array\r
+\r
+  @retval  0        The application exited normally.\r
+  @retval  Other    An error occurred.\r
+**/\r
+int\r
+main (\r
+  IN int Argc,\r
+  IN char **Argv\r
+  )\r
+{\r
+  UINTN Index;\r
+  UINT8 IpAddress[4];\r
+  struct hostent * pHost;\r
+  UINT8 * pIpAddress;\r
+  char ** ppName;\r
+  UINT32 RemoteAddress[4];\r
+\r
+  //\r
+  //  Determine if the IPv4 address is specified\r
+  //\r
+  if (( 2 != Argc )\r
+    || ( 4 != sscanf ( Argv[1],\r
+                       "%d.%d.%d.%d",\r
+                       &RemoteAddress[0],\r
+                       &RemoteAddress[1],\r
+                       &RemoteAddress[2],\r
+                       &RemoteAddress[3]))\r
+    || ( 255 < RemoteAddress [0])\r
+    || ( 255 < RemoteAddress [1])\r
+    || ( 255 < RemoteAddress [2])\r
+    || ( 255 < RemoteAddress [3])) {\r
+    Print ( L"%a  <IPv4 Address>\r\n", Argv[0]);\r
+  }\r
+  else {\r
+    //\r
+    //  Translate the address into a host name\r
+    //\r
+    IpAddress[0] = (UINT8)RemoteAddress[0];\r
+    IpAddress[1] = (UINT8)RemoteAddress[1];\r
+    IpAddress[2] = (UINT8)RemoteAddress[2];\r
+    IpAddress[3] = (UINT8)RemoteAddress[3];\r
+    pHost = gethostbyaddr ( &IpAddress[0], INADDRSZ, AF_INET );\r
+    if ( NULL == pHost ) {\r
+      Print ( L"ERROR - host not found, errno: %d\r\n", errno );\r
+    }\r
+    else {\r
+      pIpAddress = (UINT8 *)pHost->h_addr_list [ 0 ];\r
+      Print ( L"%d.%d.%d.%d, %a\r\n",\r
+              pIpAddress[0],\r
+              pIpAddress[1],\r
+              pIpAddress[2],\r
+              pIpAddress[3],\r
+              pHost->h_name );\r
+\r
+      //\r
+      //  Display the other addresses\r
+      //\r
+      for ( Index = 1; NULL != pHost->h_addr_list[Index]; Index++ ) {\r
+        pIpAddress = (UINT8 *)pHost->h_addr_list[Index];\r
+        Print ( L"%d.%d.%d.%d\r\n",\r
+                pIpAddress[0],\r
+                pIpAddress[1],\r
+                pIpAddress[2],\r
+                pIpAddress[3]);\r
+      }\r
+\r
+      //\r
+      //  Display the list of aliases\r
+      //\r
+      ppName = pHost->h_aliases;\r
+      if (( NULL == ppName ) || ( NULL == *ppName )) {\r
+        Print ( L"No aliases\r\n" );\r
+      }\r
+      else {\r
+        Print ( L"Aliases: " );\r
+        while ( NULL != *ppName ) {\r
+          //\r
+          //  Display the alias\r
+          //\r
+          Print ( L"%a", *ppName );\r
+\r
+          //\r
+          //  Set the next alias\r
+          //\r
+          ppName += 1;\r
+          if ( NULL != *ppName ) {\r
+            Print ( L", " );\r
+          }\r
+        }\r
+        Print ( L"\r\n" );\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  All done\r
+  //\r
+  return errno;\r
+}\r
diff --git a/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.inf b/AppPkg/Applications/Sockets/GetHostByAddr/GetHostByAddr.inf
new file mode 100644 (file)
index 0000000..f31b827
--- /dev/null
@@ -0,0 +1,65 @@
+#/** @file\r
+#  GetHostByAddr Application\r
+#\r
+# This file contains an 'Intel Peripheral Driver' and is      \r
+# licensed for Intel CPUs and chipsets under the terms of your\r
+# license agreement with Intel or your vendor.  This file may \r
+# be modified by the user, subject to additional terms of the \r
+# license agreement                                           \r
+#\r
+#\r
+# Copyright (c)  20011 Intel Corporation. All rights reserved\r
+# This software and associated documentation (if any) is furnished\r
+# under a license and may only be used or copied in accordance\r
+# with the terms of the license. Except as permitted by such\r
+# license, no part of this software or documentation may be\r
+# reproduced, stored in a retrieval system, or transmitted in any\r
+# form or by any means without the express written consent of\r
+# Intel Corporation.\r
+#\r
+##\r
+\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = GetHostByAddr\r
+  FILE_GUID                      = C31A6189-639A-458b-B040-D7D506CA8F4F\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = ShellCEntryLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  GetHostByAddr.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  StdLib/StdLib.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  BsdSocketLib\r
+  DebugLib\r
+  DevShell\r
+  EfiSocketLib\r
+  LibC\r
+  LibMath\r
+  LibNetUtil\r
+  ShellCEntryLib\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+#  UseSocketDxe\r
+\r
+[BuildOptions]\r
+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186\r
+   MSFT:*_*_*_CC_FLAGS = /Od\r
+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable\r
+\r
diff --git a/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.c b/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.c
new file mode 100644 (file)
index 0000000..47453ac
--- /dev/null
@@ -0,0 +1,85 @@
+/** @file\r
+  Translate the host name into an IP address\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <errno.h>\r
+#include <netdb.h>\r
+#include <string.h>\r
+#include <Uefi.h>\r
+#include <unistd.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <sys/socket.h>\r
+\r
+struct hostent * _gethostbydnsname(const char *, int);\r
+\r
+char mBuffer [65536];\r
+\r
+\r
+/**\r
+  Translate the host name into an IP address\r
+\r
+  @param [in] Argc  The number of arguments\r
+  @param [in] Argv  The argument value array\r
+\r
+  @retval  0        The application exited normally.\r
+  @retval  Other    An error occurred.\r
+**/\r
+int\r
+main (\r
+  IN int Argc,\r
+  IN char **Argv\r
+  )\r
+{\r
+  int AppStatus;\r
+  UINT8 * pIpAddress;\r
+  struct hostent * pHost;\r
+\r
+  DEBUG (( DEBUG_INFO,\r
+            "%a starting\r\n",\r
+            Argv[0]));\r
+\r
+  //\r
+  //  Determine if the host name is specified\r
+  //\r
+  AppStatus = 0;\r
+  if ( 1 == Argc ) {\r
+    Print ( L"%a  <host name>\r\n", Argv[0]);\r
+  }\r
+  else {\r
+    //\r
+    //  Translate the host name\r
+    //\r
+    pHost = _gethostbydnsname ( Argv[1], AF_INET );\r
+    if ( NULL == pHost ) {\r
+      Print ( L"ERROR - host not found, errno: %d\r\n", errno );\r
+    }\r
+    else {\r
+      pIpAddress = (UINT8 *)pHost->h_addr;\r
+      Print ( L"%a: Type %d, %d.%d.%d.%d\r\n",\r
+              pHost->h_name,\r
+              pHost->h_addrtype,\r
+              pIpAddress[0],\r
+              pIpAddress[1],\r
+              pIpAddress[2],\r
+              pIpAddress[3]);\r
+    }\r
+  }\r
+\r
+  //\r
+  //  All done\r
+  //\r
+  return errno;\r
+}\r
diff --git a/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.inf b/AppPkg/Applications/Sockets/GetHostByDns/GetHostByDns.inf
new file mode 100644 (file)
index 0000000..417eb5e
--- /dev/null
@@ -0,0 +1,65 @@
+#/** @file\r
+#  GetHostByDns Application\r
+#\r
+# This file contains an 'Intel Peripheral Driver' and is      \r
+# licensed for Intel CPUs and chipsets under the terms of your\r
+# license agreement with Intel or your vendor.  This file may \r
+# be modified by the user, subject to additional terms of the \r
+# license agreement                                           \r
+#\r
+#\r
+# Copyright (c)  20011 Intel Corporation. All rights reserved\r
+# This software and associated documentation (if any) is furnished\r
+# under a license and may only be used or copied in accordance\r
+# with the terms of the license. Except as permitted by such\r
+# license, no part of this software or documentation may be\r
+# reproduced, stored in a retrieval system, or transmitted in any\r
+# form or by any means without the express written consent of\r
+# Intel Corporation.\r
+#\r
+##\r
+\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = GetHostByDns\r
+  FILE_GUID                      = 3698D2B0-E727-4537-A636-A8770736ABFB\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = ShellCEntryLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  GetHostByDns.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  StdLib/StdLib.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  BsdSocketLib\r
+  DebugLib\r
+  DevShell\r
+  EfiSocketLib\r
+  LibC\r
+  LibMath\r
+  LibNetUtil\r
+  ShellCEntryLib\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+#  UseSocketDxe\r
+\r
+[BuildOptions]\r
+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186\r
+   MSFT:*_*_*_CC_FLAGS = /Od\r
+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable\r
+\r
diff --git a/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.c b/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.c
new file mode 100644 (file)
index 0000000..d539c99
--- /dev/null
@@ -0,0 +1,123 @@
+/** @file\r
+  Translate the host name into an IP address\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <errno.h>\r
+#include <netdb.h>\r
+#include <string.h>\r
+#include <Uefi.h>\r
+#include <unistd.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <sys/socket.h>\r
+\r
+char mBuffer [65536];\r
+\r
+\r
+/**\r
+  Translate the host name into an IP address\r
+\r
+  @param [in] Argc  The number of arguments\r
+  @param [in] Argv  The argument value array\r
+\r
+  @retval  0        The application exited normally.\r
+  @retval  Other    An error occurred.\r
+**/\r
+int\r
+main (\r
+  IN int Argc,\r
+  IN char **Argv\r
+  )\r
+{\r
+  int AppStatus;\r
+  UINTN Index;\r
+  struct hostent * pHost;\r
+  UINT8 * pIpAddress;\r
+  char ** ppName;\r
+\r
+  DEBUG (( DEBUG_INFO,\r
+            "%a starting\r\n",\r
+            Argv[0]));\r
+\r
+  //\r
+  //  Determine if the host name is specified\r
+  //\r
+  AppStatus = 0;\r
+  if ( 1 == Argc ) {\r
+    Print ( L"%a  <host name>\r\n", Argv[0]);\r
+  }\r
+  else {\r
+    //\r
+    //  Translate the host name\r
+    //\r
+    pHost = gethostbyname ( Argv[1]);\r
+    if ( NULL == pHost ) {\r
+      Print ( L"ERROR - host not found, errno: %d\r\n", errno );\r
+    }\r
+    else {\r
+      pIpAddress = (UINT8 *)pHost->h_addr;\r
+      Print ( L"%d.%d.%d.%d, Type %d, %a\r\n",\r
+              pIpAddress[0],\r
+              pIpAddress[1],\r
+              pIpAddress[2],\r
+              pIpAddress[3],\r
+              pHost->h_addrtype,\r
+              pHost->h_name );\r
+\r
+      //\r
+      //  Display the other addresses\r
+      //\r
+      for ( Index = 1; NULL != pHost->h_addr_list[Index]; Index++ ) {\r
+        pIpAddress = (UINT8 *)pHost->h_addr_list[Index];\r
+        Print ( L"%d.%d.%d.%d\r\n",\r
+                pIpAddress[0],\r
+                pIpAddress[1],\r
+                pIpAddress[2],\r
+                pIpAddress[3]);\r
+      }\r
+\r
+      //\r
+      //  Display the list of aliases\r
+      //\r
+      ppName = pHost->h_aliases;\r
+      if (( NULL == ppName ) || ( NULL == *ppName )) {\r
+        Print ( L"No aliases\r\n" );\r
+      }\r
+      else {\r
+        Print ( L"Aliases: " );\r
+        while ( NULL != *ppName ) {\r
+          //\r
+          //  Display the alias\r
+          //\r
+          Print ( L"%a", *ppName );\r
+\r
+          //\r
+          //  Set the next alias\r
+          //\r
+          ppName += 1;\r
+          if ( NULL != *ppName ) {\r
+            Print ( L", " );\r
+          }\r
+        }\r
+        Print ( L"\r\n" );\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  All done\r
+  //\r
+  return errno;\r
+}\r
diff --git a/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.inf b/AppPkg/Applications/Sockets/GetHostByName/GetHostByName.inf
new file mode 100644 (file)
index 0000000..48beb2a
--- /dev/null
@@ -0,0 +1,65 @@
+#/** @file\r
+#  GetHostByName Application\r
+#\r
+# This file contains an 'Intel Peripheral Driver' and is      \r
+# licensed for Intel CPUs and chipsets under the terms of your\r
+# license agreement with Intel or your vendor.  This file may \r
+# be modified by the user, subject to additional terms of the \r
+# license agreement                                           \r
+#\r
+#\r
+# Copyright (c)  20011 Intel Corporation. All rights reserved\r
+# This software and associated documentation (if any) is furnished\r
+# under a license and may only be used or copied in accordance\r
+# with the terms of the license. Except as permitted by such\r
+# license, no part of this software or documentation may be\r
+# reproduced, stored in a retrieval system, or transmitted in any\r
+# form or by any means without the express written consent of\r
+# Intel Corporation.\r
+#\r
+##\r
+\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = GetHostByName\r
+  FILE_GUID                      = 70FB9CE0-2CB1-4fd7-80EE-AB4B6CF4B43F\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = ShellCEntryLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  GetHostByName.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  StdLib/StdLib.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  BsdSocketLib\r
+  DebugLib\r
+  DevShell\r
+  EfiSocketLib\r
+  LibC\r
+  LibMath\r
+  LibNetUtil\r
+  ShellCEntryLib\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+#  UseSocketDxe\r
+\r
+[BuildOptions]\r
+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186\r
+   MSFT:*_*_*_CC_FLAGS = /Od\r
+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable\r
+\r
diff --git a/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.c b/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.c
new file mode 100644 (file)
index 0000000..51d8c6d
--- /dev/null
@@ -0,0 +1,89 @@
+/** @file\r
+  Translate the IPv4 address into a network name\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <errno.h>\r
+#include <netdb.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <Uefi.h>\r
+#include <unistd.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <sys/socket.h>\r
+\r
+/**\r
+  Translate the IPv4 address into a network name\r
+\r
+  @param [in] Argc  The number of arguments\r
+  @param [in] Argv  The argument value array\r
+\r
+  @retval  0        The application exited normally.\r
+  @retval  Other    An error occurred.\r
+**/\r
+int\r
+main (\r
+  IN int Argc,\r
+  IN char **Argv\r
+  )\r
+{\r
+  UINT32 RemoteAddress[4];\r
+  UINT8 IpAddress[4];\r
+  struct netent * pNetwork;\r
+  \r
+  //\r
+  //  Determine if the IPv4 address is specified\r
+  //\r
+  if (( 2 != Argc )\r
+    || ( 4 != sscanf ( Argv[1],\r
+                       "%d.%d.%d.%d",\r
+                       &RemoteAddress[0],\r
+                       &RemoteAddress[1],\r
+                       &RemoteAddress[2],\r
+                       &RemoteAddress[3]))\r
+    || ( 255 < RemoteAddress [0])\r
+    || ( 255 < RemoteAddress [1])\r
+    || ( 255 < RemoteAddress [2])\r
+    || ( 255 < RemoteAddress [3])) {\r
+    Print ( L"%a  <IPv4 Address>\r\n", Argv[0]);\r
+  }\r
+  else {\r
+    //\r
+    //  Translate the address into a network name\r
+    //\r
+    IpAddress[0] = (UINT8)RemoteAddress[0];\r
+    IpAddress[1] = (UINT8)RemoteAddress[1];\r
+    IpAddress[2] = (UINT8)RemoteAddress[2];\r
+    IpAddress[3] = (UINT8)RemoteAddress[3];\r
+    pNetwork = getnetbyaddr ( *(uint32_t *)&IpAddress[0], AF_INET );\r
+    if ( NULL == pNetwork ) {\r
+      Print ( L"ERROR - network not found, errno: %d\r\n", errno );\r
+    }\r
+    else {\r
+      Print ( L"%a: %d.%d.%d.%d, 0x%08x\r\n",\r
+              pNetwork->n_name,\r
+              IpAddress[0],\r
+              IpAddress[1],\r
+              IpAddress[2],\r
+              IpAddress[3],\r
+              pNetwork->n_net );\r
+    }\r
+  }\r
+  \r
+  //\r
+  //  All done\r
+  //\r
+  return errno;\r
+}\r
diff --git a/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.inf b/AppPkg/Applications/Sockets/GetNetByAddr/GetNetByAddr.inf
new file mode 100644 (file)
index 0000000..c280d18
--- /dev/null
@@ -0,0 +1,65 @@
+#/** @file\r
+#  GetNetByAddr Application\r
+#\r
+# This file contains an 'Intel Peripheral Driver' and is      \r
+# licensed for Intel CPUs and chipsets under the terms of your\r
+# license agreement with Intel or your vendor.  This file may \r
+# be modified by the user, subject to additional terms of the \r
+# license agreement                                           \r
+#\r
+#\r
+# Copyright (c)  20011 Intel Corporation. All rights reserved\r
+# This software and associated documentation (if any) is furnished\r
+# under a license and may only be used or copied in accordance\r
+# with the terms of the license. Except as permitted by such\r
+# license, no part of this software or documentation may be\r
+# reproduced, stored in a retrieval system, or transmitted in any\r
+# form or by any means without the express written consent of\r
+# Intel Corporation.\r
+#\r
+##\r
+\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = GetNetByAddr\r
+  FILE_GUID                      = 22198FD5-4835-4842-BF31-EB957C7DD70D\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = ShellCEntryLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  GetNetByAddr.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  StdLib/StdLib.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  BsdSocketLib\r
+  DebugLib\r
+  DevShell\r
+  EfiSocketLib\r
+  LibC\r
+  LibMath\r
+  LibNetUtil\r
+  ShellCEntryLib\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+#  UseSocketDxe\r
+\r
+[BuildOptions]\r
+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186\r
+   MSFT:*_*_*_CC_FLAGS = /Od\r
+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable\r
+\r
diff --git a/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.c b/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.c
new file mode 100644 (file)
index 0000000..b3609c9
--- /dev/null
@@ -0,0 +1,83 @@
+/** @file\r
+  Translate the network name into an IP address\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <errno.h>\r
+#include <netdb.h>\r
+#include <string.h>\r
+#include <Uefi.h>\r
+#include <unistd.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <sys/socket.h>\r
+\r
+char mBuffer [65536];\r
+\r
+\r
+/**\r
+  Translate the network name into an IP address\r
+\r
+  @param [in] Argc  The number of arguments\r
+  @param [in] Argv  The argument value array\r
+\r
+  @retval  0        The application exited normally.\r
+  @retval  Other    An error occurred.\r
+**/\r
+int\r
+main (\r
+  IN int Argc,\r
+  IN char **Argv\r
+  )\r
+{\r
+  int AppStatus;\r
+  UINT8 * pIpAddress;\r
+  struct netent * pNetwork;\r
+\r
+  DEBUG (( DEBUG_INFO,\r
+            "%a starting\r\n",\r
+            Argv[0]));\r
+\r
+  //\r
+  //  Determine if the network name is specified\r
+  //\r
+  AppStatus = 0;\r
+  if ( 1 == Argc ) {\r
+    Print ( L"%a  <network name>\r\n", Argv[0]);\r
+  }\r
+  else {\r
+    //\r
+    //  Translate the net name\r
+    //\r
+    pNetwork = getnetbyname ( Argv[1]);\r
+    if ( NULL == pNetwork ) {\r
+      Print ( L"ERROR - network not found, errno: %d\r\n", errno );\r
+    }\r
+    else {\r
+      pIpAddress = (UINT8 *)pNetwork->n_net;\r
+      Print ( L"%a: Type %d, %d.%d.%d.%d\r\n",\r
+              pNetwork->n_name,\r
+              pNetwork->n_addrtype,\r
+              pIpAddress[0],\r
+              pIpAddress[1],\r
+              pIpAddress[2],\r
+              pIpAddress[3]);\r
+    }\r
+  }\r
+\r
+  //\r
+  //  All done\r
+  //\r
+  return errno;\r
+}\r
diff --git a/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.inf b/AppPkg/Applications/Sockets/GetNetByName/GetNetByName.inf
new file mode 100644 (file)
index 0000000..1b9764e
--- /dev/null
@@ -0,0 +1,65 @@
+#/** @file\r
+#  GetNetByName Application\r
+#\r
+# This file contains an 'Intel Peripheral Driver' and is      \r
+# licensed for Intel CPUs and chipsets under the terms of your\r
+# license agreement with Intel or your vendor.  This file may \r
+# be modified by the user, subject to additional terms of the \r
+# license agreement                                           \r
+#\r
+#\r
+# Copyright (c)  20011 Intel Corporation. All rights reserved\r
+# This software and associated documentation (if any) is furnished\r
+# under a license and may only be used or copied in accordance\r
+# with the terms of the license. Except as permitted by such\r
+# license, no part of this software or documentation may be\r
+# reproduced, stored in a retrieval system, or transmitted in any\r
+# form or by any means without the express written consent of\r
+# Intel Corporation.\r
+#\r
+##\r
+\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = GetNetByName\r
+  FILE_GUID                      = DAF7B0E6-32DE-4619-B63A-2B9173A75B14\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = ShellCEntryLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  GetNetByName.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  StdLib/StdLib.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  BsdSocketLib\r
+  DebugLib\r
+  DevShell\r
+  EfiSocketLib\r
+  LibC\r
+  LibMath\r
+  LibNetUtil\r
+  ShellCEntryLib\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+#  UseSocketDxe\r
+\r
+[BuildOptions]\r
+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186\r
+   MSFT:*_*_*_CC_FLAGS = /Od\r
+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable\r
+\r
diff --git a/AppPkg/Applications/Sockets/GetServByName/GetServByName.c b/AppPkg/Applications/Sockets/GetServByName/GetServByName.c
new file mode 100644 (file)
index 0000000..d7237d3
--- /dev/null
@@ -0,0 +1,76 @@
+/** @file\r
+  Translate the service name into a port number\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <errno.h>\r
+#include <netdb.h>\r
+#include <string.h>\r
+#include <Uefi.h>\r
+#include <unistd.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <sys/socket.h>\r
+\r
+char mBuffer [65536];\r
+\r
+\r
+/**\r
+  Translate the service name into a port number\r
+\r
+  @param [in] Argc  The number of arguments\r
+  @param [in] Argv  The argument value array\r
+\r
+  @retval  0        The application exited normally.\r
+  @retval  Other    An error occurred.\r
+**/\r
+int\r
+main (\r
+  IN int Argc,\r
+  IN char **Argv\r
+  )\r
+{\r
+  int AppStatus;\r
+  int PortNumber;\r
+  struct servent * pService;\r
+\r
+  //\r
+  //  Determine if the service name is specified\r
+  //\r
+  AppStatus = 0;\r
+  if ( 1 == Argc ) {\r
+    Print ( L"%a  <service name>\r\n", Argv[0]);\r
+  }\r
+  else {\r
+    //\r
+    //  Translate the service name\r
+    //\r
+    pService = getservbyname ( Argv[1], NULL );\r
+    if ( NULL == pService ) {\r
+      Print ( L"ERROR - service not found, errno: %d\r\n", errno );\r
+    }\r
+    else {\r
+      PortNumber = htons ( pService->s_port );\r
+      Print ( L"%a: %d, %a\r\n",\r
+              pService->s_name,\r
+              PortNumber,\r
+              pService->s_proto );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  All done\r
+  //\r
+  return errno;\r
+}\r
diff --git a/AppPkg/Applications/Sockets/GetServByName/GetServByName.inf b/AppPkg/Applications/Sockets/GetServByName/GetServByName.inf
new file mode 100644 (file)
index 0000000..290d15e
--- /dev/null
@@ -0,0 +1,65 @@
+#/** @file\r
+#  GetServByName Application\r
+#\r
+# This file contains an 'Intel Peripheral Driver' and is      \r
+# licensed for Intel CPUs and chipsets under the terms of your\r
+# license agreement with Intel or your vendor.  This file may \r
+# be modified by the user, subject to additional terms of the \r
+# license agreement                                           \r
+#\r
+#\r
+# Copyright (c)  20011 Intel Corporation. All rights reserved\r
+# This software and associated documentation (if any) is furnished\r
+# under a license and may only be used or copied in accordance\r
+# with the terms of the license. Except as permitted by such\r
+# license, no part of this software or documentation may be\r
+# reproduced, stored in a retrieval system, or transmitted in any\r
+# form or by any means without the express written consent of\r
+# Intel Corporation.\r
+#\r
+##\r
+\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = GetServByName\r
+  FILE_GUID                      = 5D1F3F9E-8CEE-4299-93C2-4C64EBB58977\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = ShellCEntryLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  GetServByName.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  StdLib/StdLib.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  BsdSocketLib\r
+  DebugLib\r
+  DevShell\r
+  EfiSocketLib\r
+  LibC\r
+  LibMath\r
+  LibNetUtil\r
+  ShellCEntryLib\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+#  UseSocketDxe\r
+\r
+[BuildOptions]\r
+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186\r
+   MSFT:*_*_*_CC_FLAGS = /Od\r
+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable\r
+\r
diff --git a/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.c b/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.c
new file mode 100644 (file)
index 0000000..6a5fc46
--- /dev/null
@@ -0,0 +1,77 @@
+/** @file\r
+  Translate the port number into a service name\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <errno.h>\r
+#include <netdb.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <Uefi.h>\r
+#include <unistd.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <sys/socket.h>\r
+\r
+char mBuffer [65536];\r
+\r
+\r
+/**\r
+  Translate the port number into a service name\r
+\r
+  @param [in] Argc  The number of arguments\r
+  @param [in] Argv  The argument value array\r
+\r
+  @retval  0        The application exited normally.\r
+  @retval  Other    An error occurred.\r
+**/\r
+int\r
+main (\r
+  IN int Argc,\r
+  IN char **Argv\r
+  )\r
+{\r
+  int AppStatus;\r
+  int PortNumber;\r
+  struct servent * pService;\r
+\r
+  //\r
+  //  Determine if the service name is specified\r
+  //\r
+  AppStatus = 0;\r
+  if (( 2 != Argc )\r
+    || ( 1 != sscanf ( Argv[1], "%d", &PortNumber ))) {\r
+    Print ( L"%a  <port number>\r\n", Argv[0]);\r
+  }\r
+  else {\r
+    //\r
+    //  Translate the port number\r
+    //\r
+    pService = getservbyport ( htons ( PortNumber ), NULL );\r
+    if ( NULL == pService ) {\r
+      Print ( L"ERROR - service not found, errno: %d\r\n", errno );\r
+    }\r
+    else {\r
+      Print ( L"%a: %d, %a\r\n",\r
+              pService->s_name,\r
+              PortNumber,\r
+              pService->s_proto );\r
+    }\r
+  }\r
+\r
+  //\r
+  //  All done\r
+  //\r
+  return errno;\r
+}\r
diff --git a/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.inf b/AppPkg/Applications/Sockets/GetServByPort/GetServByPort.inf
new file mode 100644 (file)
index 0000000..1a232c0
--- /dev/null
@@ -0,0 +1,65 @@
+#/** @file\r
+#  GetServByPort Application\r
+#\r
+# This file contains an 'Intel Peripheral Driver' and is      \r
+# licensed for Intel CPUs and chipsets under the terms of your\r
+# license agreement with Intel or your vendor.  This file may \r
+# be modified by the user, subject to additional terms of the \r
+# license agreement                                           \r
+#\r
+#\r
+# Copyright (c)  20011 Intel Corporation. All rights reserved\r
+# This software and associated documentation (if any) is furnished\r
+# under a license and may only be used or copied in accordance\r
+# with the terms of the license. Except as permitted by such\r
+# license, no part of this software or documentation may be\r
+# reproduced, stored in a retrieval system, or transmitted in any\r
+# form or by any means without the express written consent of\r
+# Intel Corporation.\r
+#\r
+##\r
+\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = GetServByPort\r
+  FILE_GUID                      = 83381B06-2EEA-4cf3-9B5F-D75B9B5C93DE\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = ShellCEntryLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  GetServByPort.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  StdLib/StdLib.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  BsdSocketLib\r
+  DebugLib\r
+  DevShell\r
+  EfiSocketLib\r
+  LibC\r
+  LibMath\r
+  LibNetUtil\r
+  ShellCEntryLib\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+#  UseSocketDxe\r
+\r
+[BuildOptions]\r
+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186\r
+   MSFT:*_*_*_CC_FLAGS = /Od\r
+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable\r
+\r
diff --git a/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.c b/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.c
new file mode 100644 (file)
index 0000000..7809e80
--- /dev/null
@@ -0,0 +1,116 @@
+/** @file\r
+  Receive a datagram\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <errno.h>\r
+#include <string.h>\r
+#include <Uefi.h>\r
+#include <unistd.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <netinet/in.h>\r
+\r
+#include <sys/socket.h>\r
+#include <sys/time.h>\r
+\r
+UINT8 mBuffer [ 65536 ];\r
+\r
+/**\r
+  Receive a datagram\r
+\r
+  @param [in] Argc  The number of arguments\r
+  @param [in] Argv  The argument value array\r
+\r
+  @retval  0        The application exited normally.\r
+  @retval  Other    An error occurred.\r
+**/\r
+int\r
+main (\r
+  IN int Argc,\r
+  IN char **Argv\r
+  )\r
+{\r
+  struct sockaddr_in Address;\r
+  socklen_t AddressLength;\r
+  ssize_t LengthInBytes;\r
+  int s;\r
+  int Status;\r
+  struct timeval Timeout;\r
+  \r
+\r
+  DEBUG (( DEBUG_INFO,\r
+            "%a starting\r\n",\r
+            Argv[0]));\r
+\r
+  //\r
+  //  Get the socket\r
+  //\r
+  s = socket ( AF_INET, SOCK_DGRAM, 0 );\r
+  if ( -1 == s ) {\r
+    Print ( L"ERROR - Unable to open the socket, errno: %d\r\n", errno );\r
+  }\r
+  else {\r
+    Timeout.tv_sec = 5;\r
+    Timeout.tv_usec = 0;\r
+    Status = setsockopt ( s,\r
+                          SOL_SOCKET,\r
+                          SO_RCVTIMEO,\r
+                          &Timeout,\r
+                          sizeof ( Timeout ));\r
+    if ( -1 == Status ) {\r
+      Print ( L"ERROR - Unable to set the receive timeout, errno: %d\r\n", errno );\r
+    }\r
+    else {\r
+      AddressLength = sizeof ( Address );\r
+      LengthInBytes = recvfrom ( s,\r
+                                 &mBuffer[0],\r
+                                 sizeof ( mBuffer[0]),\r
+                                 0,\r
+                                 (struct sockaddr *)&Address,\r
+                                 &AddressLength );\r
+      if ( -1 == LengthInBytes ) {\r
+        if ( ETIMEDOUT == errno ) {\r
+          Print ( L"No datagram received\r\n" );\r
+        }\r
+        else {\r
+          Print ( L"ERROR - No datagram received, errno: %d\r\n", errno );\r
+        }\r
+      }\r
+      else {\r
+        Print ( L"Received %d bytes from %d.%d.%d.%d:%d\r\n",\r
+                LengthInBytes,\r
+                (UINT8)Address.sin_addr.s_addr,\r
+                (UINT8)( Address.sin_addr.s_addr >> 8 ),\r
+                (UINT8)( Address.sin_addr.s_addr >> 16 ),\r
+                (UINT8)( Address.sin_addr.s_addr >> 24 ),\r
+                htons ( Address.sin_port ));\r
+      }\r
+    }\r
+\r
+    //\r
+    //  Done with the socket\r
+    //\r
+    close ( s );\r
+  }\r
+\r
+  //\r
+  //  All done\r
+  //\r
+  DEBUG (( DEBUG_INFO,\r
+            "%a exiting, errno: %d\r\n",\r
+            Argv[0],\r
+            errno ));\r
+  return errno;\r
+}\r
diff --git a/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.inf b/AppPkg/Applications/Sockets/RecvDgram/RecvDgram.inf
new file mode 100644 (file)
index 0000000..bef842a
--- /dev/null
@@ -0,0 +1,64 @@
+#/** @file\r
+#  Receive Datagram Application\r
+#\r
+# This file contains an 'Intel Peripheral Driver' and is      \r
+# licensed for Intel CPUs and chipsets under the terms of your\r
+# license agreement with Intel or your vendor.  This file may \r
+# be modified by the user, subject to additional terms of the \r
+# license agreement                                           \r
+#\r
+#\r
+# Copyright (c)  20011 Intel Corporation. All rights reserved\r
+# This software and associated documentation (if any) is furnished\r
+# under a license and may only be used or copied in accordance\r
+# with the terms of the license. Except as permitted by such\r
+# license, no part of this software or documentation may be\r
+# reproduced, stored in a retrieval system, or transmitted in any\r
+# form or by any means without the express written consent of\r
+# Intel Corporation.\r
+#\r
+##\r
+\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = RecvDgram\r
+  FILE_GUID                      = 929189C9-0670-4c0b-AF7D-135D1550C8C0\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = ShellCEntryLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  RecvDgram.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  StdLib/StdLib.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  BsdSocketLib\r
+  DebugLib\r
+  DevShell\r
+  EfiSocketLib\r
+  LibC\r
+  LibMath\r
+  ShellCEntryLib\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+#  UseSocketDxe\r
+\r
+[BuildOptions]\r
+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186\r
+   MSFT:*_*_*_CC_FLAGS = /Od\r
+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable\r
+\r
diff --git a/AppPkg/Applications/Sockets/SetHostName/SetHostName.c b/AppPkg/Applications/Sockets/SetHostName/SetHostName.c
new file mode 100644 (file)
index 0000000..85dc1c4
--- /dev/null
@@ -0,0 +1,100 @@
+/** @file\r
+  Set the host name\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <errno.h>\r
+#include <string.h>\r
+#include <Uefi.h>\r
+#include <unistd.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <sys/socket.h>\r
+\r
+char mBuffer [65536];\r
+\r
+\r
+/**\r
+  Set the host name\r
+\r
+  @param [in] Argc  The number of arguments\r
+  @param [in] Argv  The argument value array\r
+\r
+  @retval  0        The application exited normally.\r
+  @retval  Other    An error occurred.\r
+**/\r
+int\r
+main (\r
+  IN int Argc,\r
+  IN char **Argv\r
+  )\r
+{\r
+  int AppStatus;\r
+\r
+  DEBUG (( DEBUG_INFO,\r
+            "%a starting\r\n",\r
+            Argv[0]));\r
+\r
+  //\r
+  //  Determine if the host name is specified\r
+  //\r
+  AppStatus = 0;\r
+  if ( 1 < Argc ) {\r
+    //\r
+    //  Set the host name\r
+    //\r
+    AppStatus = sethostname ( Argv[1], strlen ( Argv[1]));\r
+    if ( -1 == AppStatus ) {\r
+      switch ( errno ) {\r
+      default:\r
+        Print ( L"ERROR - errno: %d\r\n", errno );\r
+        break;\r
+\r
+      case ENODEV:\r
+        Print ( L"WARNING - Plarform does not support permanent storage!\r\n" );\r
+        break;\r
+\r
+      case ENOMEM:\r
+        Print ( L"ERROR - Insufficient storage to save host name!\r\n" );\r
+        break;\r
+\r
+      case ENOTSUP:\r
+        Print ( L"ERROR - Platform does not support environment variable storage!\r\n" );\r
+        break;\r
+      }\r
+    }\r
+  }\r
+  else {\r
+    //\r
+    //  Display the current host name\r
+    //\r
+    AppStatus = gethostname ( &mBuffer[0], sizeof ( mBuffer ));\r
+    if ( -1 == AppStatus ) {\r
+      Print ( L"ERROR - Unable to get host name, errno: %d\r\n", errno );\r
+    }\r
+    else {\r
+      if ( 0 == mBuffer[0]) {\r
+        Print ( L"Host name is not set!\r\n" );\r
+      }\r
+      else {\r
+        Print ( L"Host name: %a", &mBuffer[0]);\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  All done\r
+  //\r
+  return errno;\r
+}\r
diff --git a/AppPkg/Applications/Sockets/SetHostName/SetHostName.inf b/AppPkg/Applications/Sockets/SetHostName/SetHostName.inf
new file mode 100644 (file)
index 0000000..2b0bdc7
--- /dev/null
@@ -0,0 +1,64 @@
+#/** @file\r
+#  SetHostName Application\r
+#\r
+# This file contains an 'Intel Peripheral Driver' and is      \r
+# licensed for Intel CPUs and chipsets under the terms of your\r
+# license agreement with Intel or your vendor.  This file may \r
+# be modified by the user, subject to additional terms of the \r
+# license agreement                                           \r
+#\r
+#\r
+# Copyright (c)  20011 Intel Corporation. All rights reserved\r
+# This software and associated documentation (if any) is furnished\r
+# under a license and may only be used or copied in accordance\r
+# with the terms of the license. Except as permitted by such\r
+# license, no part of this software or documentation may be\r
+# reproduced, stored in a retrieval system, or transmitted in any\r
+# form or by any means without the express written consent of\r
+# Intel Corporation.\r
+#\r
+##\r
+\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SetHostName\r
+  FILE_GUID                      = 4BC80B15-255D-4858-8072-51D6D98CF90E\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = ShellCEntryLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  SetHostName.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  StdLib/StdLib.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  BsdSocketLib\r
+  DebugLib\r
+  DevShell\r
+  EfiSocketLib\r
+  LibC\r
+  LibMath\r
+  ShellCEntryLib\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+#  UseSocketDxe\r
+\r
+[BuildOptions]\r
+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186\r
+   MSFT:*_*_*_CC_FLAGS = /Od\r
+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable\r
+\r
diff --git a/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.c b/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.c
new file mode 100644 (file)
index 0000000..fdc4552
--- /dev/null
@@ -0,0 +1,379 @@
+/** @file\r
+  Set the socket options\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <errno.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <Uefi.h>\r
+#include <unistd.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <sys/socket.h>\r
+#include <sys/time.h>\r
+\r
+typedef enum _DATA_TYPE {\r
+  DATA_TYPE_UNKNOWN = 0,\r
+  DATA_TYPE_INT32_DECIMAL,\r
+  DATA_TYPE_SOCKET_TYPE,\r
+  DATA_TYPE_TIMEVAL\r
+} DATA_TYPE;\r
+\r
+typedef struct {\r
+  char * pOptionName;\r
+  int OptionValue;\r
+  int OptionLevel;\r
+  BOOLEAN bSetAllowed;\r
+  DATA_TYPE DataType;\r
+} OPTIONS;\r
+\r
+CONST OPTIONS mOptions [] = {\r
+  { "SO_ACCEPTCONN", SO_ACCEPTCONN, SOL_SOCKET, FALSE, DATA_TYPE_UNKNOWN },\r
+  { "SO_BROADCAST", SO_BROADCAST, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },\r
+  { "SO_DEBUG", SO_DEBUG, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },\r
+  { "SO_DONTROUTE", SO_DONTROUTE, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },\r
+  { "SO_ERROR", SO_ERROR, SOL_SOCKET, FALSE, DATA_TYPE_UNKNOWN },\r
+  { "SO_KEEPALIVE", SO_KEEPALIVE, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },\r
+  { "SO_OOBINLINE", SO_OOBINLINE, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },\r
+  { "SO_OVERFLOWED", SO_OVERFLOWED, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },\r
+  { "SO_RCVBUF", SO_RCVBUF, SOL_SOCKET, TRUE, DATA_TYPE_INT32_DECIMAL },\r
+  { "SO_RCVLOWAT", SO_RCVLOWAT, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },\r
+  { "SO_RCVTIMEO", SO_RCVTIMEO, SOL_SOCKET, TRUE, DATA_TYPE_TIMEVAL },\r
+  { "SO_REUSEADDR", SO_REUSEADDR, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },\r
+  { "SO_REUSEPORT", SO_REUSEPORT, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },\r
+  { "SO_SNDBUF", SO_SNDBUF, SOL_SOCKET, TRUE, DATA_TYPE_INT32_DECIMAL },\r
+  { "SO_SNDLOWAT", SO_SNDLOWAT, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },\r
+  { "SO_SNDTIMEO", SO_SNDTIMEO, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },\r
+  { "SO_TIMESTAMP", SO_TIMESTAMP, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN },\r
+  { "SO_TYPE", SO_TYPE, SOL_SOCKET, FALSE, DATA_TYPE_SOCKET_TYPE },\r
+  { "SO_USELOOPBACK", SO_USELOOPBACK, SOL_SOCKET, TRUE, DATA_TYPE_UNKNOWN }\r
+};\r
+\r
+\r
+UINT8 mBuffer [ 65536 ];\r
+UINT8 mValue [ 65536 ];\r
+char * mSocketType [] = {\r
+  "SOCK_STREAM",\r
+  "SOCK_DGRAM",\r
+  "SOCK_RAW",\r
+  "SOCK_RDM",\r
+  "SOCK_SEQPACKET"\r
+};\r
+\r
+void\r
+DisplayOption (\r
+  CONST OPTIONS * pOption,\r
+  socklen_t LengthInBytes,\r
+  BOOLEAN bDisplayUpdate,\r
+  BOOLEAN bDisplayCrLf\r
+  )\r
+{\r
+  UINT8 * pEnd;\r
+  char * pString;\r
+  union {\r
+    UINT8 * u8;\r
+    INT32 * i32;\r
+    struct timeval * TimeVal;\r
+  } Value;\r
+\r
+  //\r
+  //  Display the value length\r
+  //\r
+  if ( !bDisplayUpdate ) {\r
+    Print ( L"LengthInBytes: %d\r\n", LengthInBytes );\r
+    Print ( L"%a: ", pOption->pOptionName );\r
+  }\r
+  else {\r
+    Print ( L" --> " );\r
+  }\r
+\r
+  //\r
+  //  Display the value\r
+  //\r
+  Value.u8 = &mBuffer[0];\r
+  switch ( pOption->DataType )\r
+  {\r
+  case DATA_TYPE_UNKNOWN:\r
+    Print ( L"%a:", pOption->pOptionName );\r
+    pEnd = &Value.u8 [ LengthInBytes ];\r
+    while ( pEnd > Value.u8 ) {\r
+      Print ( L" %02x", *Value.u8 );\r
+      Value.u8 += 1;\r
+    }\r
+    break;\r
+    \r
+  case DATA_TYPE_INT32_DECIMAL:\r
+    if ( 4 == LengthInBytes ) {\r
+      Print ( L"%d", *Value.i32 );\r
+    }\r
+    else {\r
+      errno = ( 4 > LengthInBytes ) ? EBUFSIZE : ERANGE;\r
+      Print ( L"\r\nERROR - Invalid length, errno: %d\r\n", errno );\r
+    }\r
+    break;\r
+\r
+  case DATA_TYPE_SOCKET_TYPE:\r
+    if ( 4 == LengthInBytes ) {\r
+      if (( SOCK_STREAM <= *Value.i32 ) && ( SOCK_SEQPACKET >= *Value.i32 )) {\r
+        pString = mSocketType [ *Value.i32 - SOCK_STREAM ];\r
+        Print ( L"%a", pString );\r
+      }\r
+      else {\r
+        Print ( L"%08x (unknown type)", *Value.i32 );\r
+      }\r
+    }\r
+    else {\r
+      errno = ( 4 > LengthInBytes ) ? EBUFSIZE : ERANGE;\r
+      Print ( L"\r\nERROR - Invalid length, errno: %d\r\n", errno );\r
+    }\r
+    break;\r
+\r
+  case DATA_TYPE_TIMEVAL:\r
+    if ( sizeof ( *Value.TimeVal ) == LengthInBytes ) {\r
+      if (( 0 == Value.TimeVal->tv_sec )\r
+        && ( 0 == Value.TimeVal->tv_usec )) {\r
+        Print ( L"Infinite" );\r
+      }\r
+      else {\r
+        Print ( L"%d.%06d sec",\r
+                Value.TimeVal->tv_sec,\r
+                Value.TimeVal->tv_usec );\r
+      }\r
+    }\r
+    else {\r
+      errno = ( 4 > LengthInBytes ) ? EBUFSIZE : ERANGE;\r
+      Print ( L"\r\nERROR - Invalid length, errno: %d\r\n", errno );\r
+    }\r
+    break;\r
+  }\r
+\r
+  //\r
+  //  Terminate the line\r
+  //\r
+  if ( bDisplayCrLf ) {\r
+    Print ( L"\r\n" );\r
+  }\r
+}\r
+\r
+socklen_t\r
+GetOptionValue (\r
+  CONST OPTIONS * pOption,\r
+  char * pValue\r
+  )\r
+{\r
+  socklen_t BytesToWrite;\r
+  union {\r
+    UINT8 * u8;\r
+    INT32 * i32;\r
+    struct timeval * TimeVal;\r
+  } Value;\r
+  int Values;\r
+\r
+  //\r
+  //  Assume failure\r
+  //\r
+  errno = EINVAL;\r
+  BytesToWrite = 0;\r
+\r
+  //\r
+  //  Determine the type of parameter\r
+  //\r
+  if ( pOption->bSetAllowed ) {\r
+    Value.u8 = &mValue[0];\r
+    switch ( pOption->DataType ) {\r
+    case DATA_TYPE_INT32_DECIMAL:\r
+      Values = sscanf ( pValue, "%d", Value.i32 );\r
+      if ( 1 == Values ) {\r
+        BytesToWrite = sizeof ( *Value.i32);\r
+        errno = 0;\r
+      }\r
+      break;\r
+\r
+    case DATA_TYPE_TIMEVAL:\r
+      Values = sscanf ( pValue, "%d.%0d",\r
+                        &Value.TimeVal->tv_sec,\r
+                        &Value.TimeVal->tv_usec );\r
+      if (( 2 == Values )\r
+        && ( 0 <= Value.TimeVal->tv_sec )\r
+        && ( 0 <= Value.TimeVal->tv_usec )\r
+        && ( 1000000 > Value.TimeVal->tv_usec )){\r
+        BytesToWrite = sizeof ( *Value.TimeVal );\r
+        errno = 0;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Display the error\r
+  //\r
+  if ( 0 == BytesToWrite ) {\r
+    Print ( L"ERROR - Invalid value!\r\n" );\r
+  }\r
+\r
+  //\r
+  //  Return the number of bytes to be written\r
+  //\r
+  return BytesToWrite;\r
+}\r
+\r
+\r
+/**\r
+  Set the socket options\r
+\r
+  @param [in] Argc  The number of arguments\r
+  @param [in] Argv  The argument value array\r
+\r
+  @retval  0        The application exited normally.\r
+  @retval  Other    An error occurred.\r
+**/\r
+int\r
+main (\r
+  IN int Argc,\r
+  IN char **Argv\r
+  )\r
+{\r
+  socklen_t BytesToWrite;\r
+  socklen_t LengthInBytes;\r
+  CONST OPTIONS * pEnd;\r
+  CONST OPTIONS * pOption;\r
+  int s;\r
+  int Status;\r
+\r
+  DEBUG (( DEBUG_INFO,\r
+            "%a starting\r\n",\r
+            Argv[0]));\r
+\r
+  //\r
+  //  Parse the socket option\r
+  //\r
+  pOption = &mOptions[0];\r
+  pEnd = &pOption[sizeof ( mOptions ) / sizeof ( mOptions[0])];\r
+  if ( 2 <= Argc ) {\r
+    while ( pEnd > pOption ) {\r
+      if ( 0 == strcmp ( Argv[1], pOption->pOptionName )) {\r
+        break;\r
+      }\r
+      pOption += 1;\r
+    }\r
+    if ( pEnd <= pOption ) {\r
+      Print ( L"ERROR: Invalid option: %a\r\n", Argv[1]);\r
+      Argc = 1;\r
+    }\r
+  }\r
+\r
+  //\r
+  //  Display the help if necessary\r
+  //\r
+  if (( 2 > Argc ) || ( 3 < Argc )) {\r
+    Print ( L"%a <option>\r\n", Argv[0]);\r
+    Print ( L"\r\n" );\r
+    Print ( L"Option one of:\r\n" );\r
+    pOption = &mOptions[0];\r
+    while ( pEnd > pOption ) {\r
+      Print ( L"   %a: %a\r\n",\r
+              pOption->pOptionName,\r
+              pOption->bSetAllowed ? "get/set" : "get" );\r
+      pOption += 1;\r
+    }\r
+    errno = EINVAL;\r
+  }\r
+  else {\r
+    //\r
+    //  Determine if the value is to be set\r
+    //\r
+    BytesToWrite = 0;\r
+    if (( 3 > Argc )\r
+      || ( 0 < ( BytesToWrite = GetOptionValue ( pOption, Argv [2])))) {\r
+      //\r
+      //  Get the socket\r
+      //\r
+      s = socket ( AF_INET, 0, 0 );\r
+      if ( -1 == s ) {\r
+        Print ( L"ERROR - Unable to open the socket, errno: %d\r\n", errno );\r
+      }\r
+      else {\r
+        //\r
+        //  Display the option value\r
+        //\r
+        LengthInBytes = sizeof ( mBuffer );\r
+        Status = getsockopt ( s,\r
+                              pOption->OptionLevel,\r
+                              pOption->OptionValue,\r
+                              &mBuffer,\r
+                              &LengthInBytes );\r
+        if ( -1 == Status ) {\r
+          Print ( L"ERROR - getsockopt failed, errno: %d\r\n", errno );\r
+        }\r
+        else {\r
+          DisplayOption ( pOption,\r
+                          LengthInBytes,\r
+                          FALSE,\r
+                          (BOOLEAN)( 0 == BytesToWrite ));\r
+\r
+          //\r
+          //  Determine if the value is to be set\r
+          //\r
+          if (( 0 < BytesToWrite )\r
+              && ( BytesToWrite == LengthInBytes )) {\r
+            //\r
+            //  Set the option value\r
+            //\r
+            Status = setsockopt ( s,\r
+                                  pOption->OptionLevel,\r
+                                  pOption->OptionValue,\r
+                                  &mValue,\r
+                                  BytesToWrite );\r
+            if ( -1 == Status ) {\r
+              Print ( L"ERROR - setsockopt failed, errno: %d\r\n", errno );\r
+            }\r
+            else {\r
+              //\r
+              //  Display the updated option value\r
+              //\r
+              Status = getsockopt ( s,\r
+                                    pOption->OptionLevel,\r
+                                    pOption->OptionValue,\r
+                                    &mBuffer,\r
+                                    &LengthInBytes );\r
+              if ( -1 == Status ) {\r
+                Print ( L"ERROR - getsockopt failed, errno: %d\r\n", errno );\r
+              }\r
+              else {\r
+                DisplayOption ( pOption,\r
+                                LengthInBytes,\r
+                                TRUE,\r
+                                TRUE );\r
+              }\r
+            }\r
+          }\r
+        }\r
+\r
+        //\r
+        //  Done with the socket\r
+        //\r
+        close ( s );\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  //  All done\r
+  //\r
+  DEBUG (( DEBUG_INFO,\r
+            "%a exiting, errno: %d\r\n",\r
+            Argv[0],\r
+            errno ));\r
+  return errno;\r
+}\r
diff --git a/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.inf b/AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.inf
new file mode 100644 (file)
index 0000000..835e1eb
--- /dev/null
@@ -0,0 +1,64 @@
+#/** @file\r
+#  SetHostName Application\r
+#\r
+# This file contains an 'Intel Peripheral Driver' and is      \r
+# licensed for Intel CPUs and chipsets under the terms of your\r
+# license agreement with Intel or your vendor.  This file may \r
+# be modified by the user, subject to additional terms of the \r
+# license agreement                                           \r
+#\r
+#\r
+# Copyright (c)  20011 Intel Corporation. All rights reserved\r
+# This software and associated documentation (if any) is furnished\r
+# under a license and may only be used or copied in accordance\r
+# with the terms of the license. Except as permitted by such\r
+# license, no part of this software or documentation may be\r
+# reproduced, stored in a retrieval system, or transmitted in any\r
+# form or by any means without the express written consent of\r
+# Intel Corporation.\r
+#\r
+##\r
+\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SetSockOpt\r
+  FILE_GUID                      = 6E851687-A7A9-4aa2-8DD0-673E03E51433\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = ShellCEntryLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  SetSockOpt.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  StdLib/StdLib.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  BsdSocketLib\r
+  DebugLib\r
+  DevShell\r
+  EfiSocketLib\r
+  LibC\r
+  LibMath\r
+  ShellCEntryLib\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+#  UseSocketDxe\r
+\r
+[BuildOptions]\r
+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186\r
+   MSFT:*_*_*_CC_FLAGS = /Od\r
+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable\r
+\r
diff --git a/AppPkg/Applications/Sockets/TftpServer/TftpServer.c b/AppPkg/Applications/Sockets/TftpServer/TftpServer.c
new file mode 100644 (file)
index 0000000..a1e19c2
--- /dev/null
@@ -0,0 +1,1527 @@
+/*++
+  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
+  This is a simple TFTP server application
+
+**/
+
+#include <TftpServer.h>
+
+TSDT_TFTP_SERVER mTftpServer; ///<  TFTP server's control structure
+
+
+/**
+  Add a connection context to the list of connection contexts.
+
+  @param [in] pTftpServer   The TFTP server control structure address.
+
+  @retval Context structure address, NULL if allocation fails
+
+**/
+TSDT_CONNECTION_CONTEXT *
+ContextAdd (
+  IN TSDT_TFTP_SERVER * pTftpServer
+  )
+{
+  size_t LengthInBytes;
+  TSDT_CONNECTION_CONTEXT * pContext;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Use for/break instead of goto
+  //
+  for ( ; ; ) {
+    //
+    //  Allocate a new context
+    //
+    LengthInBytes = sizeof ( *pContext );
+    Status = gBS->AllocatePool ( EfiRuntimeServicesData,
+                                 LengthInBytes,
+                                 (VOID **)&pContext );
+    if ( EFI_ERROR ( Status )) {
+      DEBUG (( DEBUG_ERROR | DEBUG_POOL,
+                "ERROR - Failed to allocate the context, Status: %r\r\n",
+                Status ));
+      pContext = NULL;
+      break;
+    }
+
+    //
+    //  Initialize the context
+    //
+    ZeroMem ( pContext, LengthInBytes );
+    CopyMem ( &pContext->RemoteAddress,
+              &pTftpServer->RemoteAddress,
+              sizeof ( pContext->RemoteAddress ));
+    pContext->BlockSize = TFTP_MAX_BLOCK_SIZE;
+    pContext->pBuffer = &pContext->FileData[0];
+    pContext->pEnd = &pContext->pBuffer[sizeof ( pContext->pBuffer )];
+    pContext->MaxTransferSize = 0;
+    pContext->MaxTransferSize -= 1;
+
+    //
+    //  Display the new context
+    //
+    DEBUG (( DEBUG_PORT_WORK | DEBUG_INFO,
+              "0x%08x: Context for %d.%d.%d.%d:%d\r\n",
+              pContext,
+              (UINT8)pContext->RemoteAddress.sin_addr.s_addr,
+              (UINT8)( pContext->RemoteAddress.sin_addr.s_addr >> 8 ),
+              (UINT8)( pContext->RemoteAddress.sin_addr.s_addr >> 16 ),
+              (UINT8)( pContext->RemoteAddress.sin_addr.s_addr >> 24 ),
+              htons ( pContext->RemoteAddress.sin_port )));
+
+    //
+    //  Add the context to the context list
+    //
+    pContext->pNext = pTftpServer->pContextList;
+    pTftpServer->pContextList = pContext;
+
+    //
+    //  All done
+    //
+    break;
+  }
+
+  //
+  //  Return the connection context
+  //
+  DBG_EXIT_STATUS ( pContext );
+  return pContext;
+}
+
+
+/**
+  Locate a remote connection context.
+
+  @param [in] pTftpServer   The TFTP server control structure address.
+
+  @param [in] pIpAddress    The start of the remote IP address in network order
+
+  @param [in] Port          The remote port number
+
+  @retval Context structure address, NULL if not found
+
+**/
+TSDT_CONNECTION_CONTEXT *
+ContextFind (
+  IN TSDT_TFTP_SERVER * pTftpServer
+  )
+{
+  TSDT_CONNECTION_CONTEXT * pContext;
+
+  DBG_ENTER ( );
+
+  //
+  //  Walk the list of connection contexts
+  //
+  pContext = pTftpServer->pContextList;
+  while ( NULL != pContext ) {
+    //
+    //  Attempt to locate the remote network connection
+    //
+    if (( pTftpServer->RemoteAddress.sin_addr.s_addr == pContext->RemoteAddress.sin_addr.s_addr )
+      && ( pTftpServer->RemoteAddress.sin_port == pContext->RemoteAddress.sin_port )) {
+      //
+      //  The connection was found
+      //
+      DEBUG (( DEBUG_TFTP_REQUEST,
+                "0x%08x: pContext found\r\n",
+                pContext ));
+      break;
+    }
+
+    //
+    //  Set the next context
+    //
+    pContext = pContext->pNext;
+  }
+
+  //
+  //  Return the connection context structure address
+  //
+  DBG_EXIT_HEX ( pContext );
+  return pContext;
+}
+
+
+/**
+  Remove a context from the list.
+
+  @param [in] pTftpServer    The TFTP server control structure address.
+
+  @param [in] pContext       The context structure address.
+
+**/
+VOID
+ContextRemove (
+  IN TSDT_TFTP_SERVER * pTftpServer,
+  IN TSDT_CONNECTION_CONTEXT * pContext
+  )
+{
+  TSDT_CONNECTION_CONTEXT * pNextContext;
+  TSDT_CONNECTION_CONTEXT * pPreviousContext;
+
+  DBG_ENTER ( );
+
+  //
+  //  Attempt to locate the context in the list
+  //
+  pPreviousContext = NULL;
+  pNextContext = pTftpServer->pContextList;
+  while ( NULL != pNextContext ) {
+    //
+    //  Determine if the context was found
+    //
+    if ( pNextContext == pContext ) {
+      //
+      //  Remove the context from the list
+      //
+      if ( NULL == pPreviousContext ) {
+        pTftpServer->pContextList = pContext->pNext;
+      }
+      else {
+        pPreviousContext->pNext = pContext->pNext;
+      }
+      break;
+    }
+
+    //
+    //  Set the next context
+    //
+    pPreviousContext = pNextContext;
+    pNextContext = pNextContext->pNext;
+  }
+
+  //
+  //  Determine if the context was found
+  //
+  if ( NULL != pContext ) {
+    //
+    //  Return the resources
+    //
+    gBS->FreePool ( pContext );
+  }
+
+  DBG_EXIT ( );
+}
+
+
+/**
+  Process the work for the sockets.
+
+  @param [in] pTftpServer   The TFTP server control structure address.
+
+**/
+VOID
+PortWork (
+  IN TSDT_TFTP_SERVER * pTftpServer
+  )
+{
+  TSDT_CONNECTION_CONTEXT * pContext;
+  socklen_t RemoteAddressLength;
+
+  DBG_ENTER ( );
+
+  //
+  //  Handle input events
+  //
+  if ( 0 != ( pTftpServer->TftpPort.revents & POLLRDNORM )) {
+    //
+    //  Receive the message from the remote system
+    //
+    RemoteAddressLength = sizeof ( pTftpServer->RemoteAddress );
+    pTftpServer->RxBytes = recvfrom ( pTftpServer->TftpPort.fd,
+                                      &pTftpServer->RxBuffer[0],
+                                      sizeof ( pTftpServer->RxBuffer ),
+                                      0,
+                                      (struct sockaddr *) &pTftpServer->RemoteAddress,
+                                      &RemoteAddressLength );
+    if ( -1 != pTftpServer->RxBytes ) {
+      pTftpServer->RemoteAddress.sin_len = (UINT8) RemoteAddressLength;
+      DEBUG (( DEBUG_TFTP_PORT,
+                 "Received %d bytes from %d.%d.%d.%d:%d\r\n",
+                 pTftpServer->RxBytes,
+                 pTftpServer->RemoteAddress.sin_addr.s_addr & 0xff,
+                 ( pTftpServer->RemoteAddress.sin_addr.s_addr >> 8 ) & 0xff,
+                 ( pTftpServer->RemoteAddress.sin_addr.s_addr >> 16 ) & 0xff,
+                 ( pTftpServer->RemoteAddress.sin_addr.s_addr >> 24 ) & 0xff,
+                 htons ( pTftpServer->RemoteAddress.sin_port )));
+
+      //
+      //  Lookup connection context using the remote system address and port
+      //  to determine if an existing connection to this remote
+      //  system exists
+      //
+      pContext = ContextFind ( pTftpServer );
+
+      //
+      //  Process the received message
+      //
+      TftpProcessRequest ( pTftpServer, pContext );
+    }
+    else {
+      //
+      //  Receive error on the TFTP server port
+      //  Close the server socket
+      //
+      DEBUG (( DEBUG_ERROR,
+                "ERROR - Failed receive on TFTP server port, errno: 0x%08x\r\n",
+                errno ));
+      pTftpServer->TftpPort.revents |= POLLHUP;
+    }
+  }
+
+  //
+  //  Handle the close event
+  //
+  if ( 0 != ( pTftpServer->TftpPort.revents & POLLHUP )) {
+    //
+    //  Close the port
+    //
+    close ( pTftpServer->TftpPort.fd );
+    pTftpServer->TftpPort.fd = -1;
+  }
+
+  DBG_EXIT ( );
+}
+
+
+/**
+  Scan the list of sockets and process any pending work
+
+  @param [in] pTftpServer   The TFTP server control structure address.
+
+**/
+VOID
+SocketPoll (
+  IN TSDT_TFTP_SERVER * pTftpServer
+  )
+{
+  int FDCount;
+
+  DEBUG (( DEBUG_SOCKET_POLL, "Entering SocketPoll\r\n" ));
+
+  //
+  //  Determine if any ports are active
+  //
+  FDCount = poll ( &pTftpServer->TftpPort,
+                   1,
+                   CLIENT_POLL_DELAY );
+  if ( -1 == FDCount ) {
+    DEBUG (( DEBUG_ERROR | DEBUG_SOCKET_POLL,
+              "ERROR - errno: %d\r\n",
+              errno ));
+  }
+
+  if ( 0 < FDCount ) {
+    //
+    //  Process this port
+    //
+    PortWork ( pTftpServer );
+    pTftpServer->TftpPort.revents = 0;
+  }
+
+  DEBUG (( DEBUG_SOCKET_POLL, "Exiting SocketPoll\r\n" ));
+}
+
+
+/**
+  Convert a character to lower case
+
+  @param [in] Character The character to convert
+
+  @returns  The lower case equivalent of the character
+
+**/
+int
+tolower (
+  int Character
+  )
+{
+  //
+  //  Determine if the character is upper case
+  //
+  if (( 'A' <= Character ) && ( 'Z' >= Character )) {
+    //
+    //  Convert the character to lower caes
+    //
+    Character += 'a' - 'A';
+  }
+
+  //
+  //  Return the converted character
+  //
+  return Character;
+}
+
+
+/**
+  Case independent string comparison
+
+  @param [in] pString1  Zero terminated string address
+  @param [in] pString2  Zero terminated string address
+
+  @returns    Returns the first character difference between string 1
+              and string 2.
+
+**/
+int
+stricmp (
+  char * pString1,
+  char * pString2
+  )
+{
+  int Char1;
+  int Char2;
+  int Difference;
+
+  //
+  //  Walk the length of the strings
+  //
+  do {
+    //
+    //  Get the next characters
+    //
+    Char1 = (UINT8)*pString1++;
+    Char2 = (UINT8)*pString2++;
+
+    //
+    //  Convert them to lower case
+    //
+    Char1 = tolower ( Char1 );
+    Char2 = tolower ( Char2 );
+
+    //
+    //  Done when the characters differ
+    //
+    Difference = Char1 - Char2;
+    if ( 0 != Difference ) {
+      break;
+    }
+
+    //
+    //  Done at the end of the string
+    //
+  } while ( 0 != Char1 );
+
+  //
+  //  Return the difference
+  //
+  return Difference;
+}
+
+
+/**
+  Get the next TFTP option
+
+  @param [in] pOption       Address of a zero terminated option string
+  @param [in] pEnd          End of buffer address
+  @param [in] ppNextOption  Address to receive the address of the next
+                            zero terminated option string
+
+  @retval EFI_SUCCESS   Message processed successfully
+
+**/
+EFI_STATUS
+TftpOptionGet (
+  IN UINT8 * pOption,
+  IN UINT8 * pEnd,
+  IN UINT8 ** ppNextOption
+  )
+{
+  UINT8 * pNextOption;
+  EFI_STATUS Status;
+
+  //
+  //  Locate the end of the option
+  //
+  pNextOption = pOption;
+  while (( pEnd > pNextOption ) && ( 0 != *pNextOption )) {
+    pNextOption += 1;
+  }
+  if ( pEnd <= pNextOption ) {
+    //
+    //  Error - end of buffer reached
+    //
+    DEBUG (( DEBUG_ERROR | DEBUG_TFTP_REQUEST,
+              "ERROR - Option without zero termination received!\r\n" ));
+    Status = EFI_INVALID_PARAMETER;
+  }
+  else {
+    //
+    //  Zero terminated option found
+    //
+    pNextOption += 1;
+
+    //
+    //  Display the zero terminated ASCII option string
+    //
+    DEBUG (( DEBUG_TFTP_REQUEST,
+              "Option: %a\r\n",
+              pOption ));
+    Status = EFI_SUCCESS;
+  }
+
+  //
+  //  Return the next option address
+  //
+  *ppNextOption = pNextOption;
+
+  //
+  //  Return the operation status
+  //
+  return Status;
+}
+
+
+/**
+  Place an option value into the option acknowledgement
+
+  @param [in] pOack     Option acknowledgement address
+  @param [in] Value     Value to translate into ASCII decimal
+
+  @returns              Option acknowledgement address
+
+**/
+UINT8 *
+TftpOptionSet (
+  IN UINT8 * pOack,
+  IN UINT64 Value
+  )
+{
+  UINT64 NextValue;
+
+  //
+  //  Determine the next value
+  //
+  NextValue = Value / 10;
+
+  //
+  //  Supress leading zeros
+  //
+  if ( 0 != NextValue ) {
+    pOack = TftpOptionSet ( pOack, NextValue );
+  }
+
+  //
+  //  Output this digit
+  //
+  *pOack++ = (UINT8)( Value - ( NextValue * 10 ) + '0' );
+
+  //
+  //  Return the next option acknowledgement location
+  //
+  return pOack;
+}
+
+
+/**
+  Process the TFTP request
+
+  @param [in] pContext  The context structure address.
+  @param [in] pOption   Address of the first zero terminated option string
+  @param [in] pEnd      End of buffer address
+
+**/
+VOID
+TftpOptions (
+  IN TSDT_CONNECTION_CONTEXT * pContext,
+  IN UINT8 * pOption,
+  IN UINT8 * pEnd
+  )
+{
+  UINT8 * pNextOption;
+  UINT8 * pOack;
+  UINT8 * pTemp;
+  UINT8 * pValue;
+  EFI_STATUS Status;
+  INT32 Value;
+
+  //
+  //  Start the OACK packet
+  //  Let the OACK handle the parsing errors
+  //  See http://tools.ietf.org/html/rfc2347
+  //
+  pOack = &pContext->TxBuffer[0];
+  *pOack++ = 0;
+  *pOack++ = TFTP_OP_OACK;
+  pContext->TxBytes = 2;
+
+  //
+  //  Walk the list of options
+  //
+  do {
+    //
+    //  Get the next option, skip junk at end of message
+    //
+    Status = TftpOptionGet ( pOption, pEnd, &pNextOption );
+    if ( !EFI_ERROR ( Status )) {
+      //
+      //  Process the option
+      //
+
+      //
+      //  blksize - See http://tools.ietf.org/html/rfc2348
+      //
+      pValue = pNextOption;
+      if ( 0 == stricmp ((char *)pOption, "blksize" )) {
+        //
+        //  Get the value
+        //
+        Status = TftpOptionGet ( pValue, pEnd, &pNextOption );
+        if ( !EFI_ERROR ( Status )) {
+          //
+          //  Validate the block size, skip non-numeric block sizes
+          //
+          Status = TftpOptionValue ( pValue, &Value );
+          if ( !EFI_ERROR ( Status )) {
+            //
+            //  Propose a smaller block size if necessary
+            //
+            if ( Value > TFTP_MAX_BLOCK_SIZE ) {
+              Value = TFTP_MAX_BLOCK_SIZE;
+            }
+
+            //
+            //  Set the new block size
+            //
+            pContext->BlockSize = Value;
+            DEBUG (( DEBUG_TFTP_REQUEST,
+                      "Using block size of %d bytes\r\n",
+                      pContext->BlockSize ));
+
+            //
+            //  Update the OACK
+            //
+            pTemp = pOack;
+            *pOack++ = 'b';
+            *pOack++ = 'l';
+            *pOack++ = 'k';
+            *pOack++ = 's';
+            *pOack++ = 'i';
+            *pOack++ = 'z';
+            *pOack++ = 'e';
+            *pOack++ = 0;
+            pOack = TftpOptionSet ( pOack, pContext->BlockSize );
+            *pOack++ = 0;
+            pContext->TxBytes += pOack - pTemp;
+          }
+        }
+      }
+
+      //
+      //  timeout - See http://tools.ietf.org/html/rfc2349
+      //
+      else if ( 0 == stricmp ((char *)pOption, "timeout" )) {
+        //
+        //  Get the value
+        //
+        Status = TftpOptionGet ( pValue, pEnd, &pNextOption );
+        if ( !EFI_ERROR ( Status )) {
+          Status = TftpOptionValue ( pValue, &Value );
+          if ( !EFI_ERROR ( Status )) {
+            //
+            //  Set the timeout value
+            //
+            pContext->Timeout = Value;
+            DEBUG (( DEBUG_TFTP_REQUEST,
+                      "Using timeout of %d seconds\r\n",
+                      pContext->Timeout ));
+
+            //
+            //  Update the OACK
+            //
+            pTemp = pOack;
+            *pOack++ = 't';
+            *pOack++ = 'i';
+            *pOack++ = 'm';
+            *pOack++ = 'e';
+            *pOack++ = 'o';
+            *pOack++ = 'u';
+            *pOack++ = 't';
+            *pOack++ = 0;
+            pOack = TftpOptionSet ( pOack, pContext->Timeout );
+            *pOack++ = 0;
+            pContext->TxBytes += pOack - pTemp;
+          }
+        }
+      }
+
+      //
+      //  tsize - See http://tools.ietf.org/html/rfc2349
+      //
+      else if ( 0 == stricmp ((char *)pOption, "tsize" )) {
+        //
+        //  Get the value
+        //
+        Status = TftpOptionGet ( pValue, pEnd, &pNextOption );
+        if ( !EFI_ERROR ( Status )) {
+          Status = TftpOptionValue ( pValue, &Value );
+          if ( !EFI_ERROR ( Status )) {
+            //
+            //  Return the file size
+            //
+            DEBUG (( DEBUG_TFTP_REQUEST,
+                      "Returning file size of %Ld bytes\r\n",
+                      pContext->LengthInBytes ));
+
+            //
+            //  Update the OACK
+            //
+            pTemp = pOack;
+            *pOack++ = 't';
+            *pOack++ = 's';
+            *pOack++ = 'i';
+            *pOack++ = 'z';
+            *pOack++ = 'e';
+            *pOack++ = 0;
+            pOack = TftpOptionSet ( pOack, pContext->LengthInBytes );
+            *pOack++ = 0;
+            pContext->TxBytes += pOack - pTemp;
+          }
+        }
+      }
+      else {
+        //
+        //  Unknown option - Ignore it
+        //
+        DEBUG (( DEBUG_WARN | DEBUG_TFTP_REQUEST,
+                  "WARNING - Skipping unknown option: %a\r\n",
+                  pOption ));
+      }
+    }
+
+    //
+    //  Set the next option
+    //
+    pOption = pNextOption;
+  } while ( pEnd > pOption );
+}
+
+
+/**
+  Process the TFTP request
+
+  @param [in] pOption   Address of the first zero terminated option string
+  @param [in] pValue    Address to receive the value
+
+  @retval EFI_SUCCESS   Option translated into a value
+
+**/
+EFI_STATUS
+TftpOptionValue (
+  IN UINT8 * pOption,
+  IN INT32 * pValue
+  )
+{
+  UINT8 Digit;
+  EFI_STATUS Status;
+  INT32 Value;
+
+  //
+  //  Assume success
+  //
+  Status = EFI_SUCCESS;
+
+  //
+  //  Walk the characters in the option
+  //
+  Value = 0;
+  while ( 0 != *pOption ) {
+    //
+    //  Convert the next digit to binary
+    //
+    Digit = *pOption++;
+    if (( '0' <= Digit ) && ( '9' >= Digit )) {
+      Value *= 10;
+      Value += Digit - '0';
+    }
+    else {
+      DEBUG (( DEBUG_ERROR | DEBUG_TFTP_REQUEST,
+                "ERROR - Invalid character '0x%02x' in the value\r\n",
+                Digit ));
+      Status = EFI_INVALID_PARAMETER;
+      break;
+    }
+  }
+
+  //
+  //  Return the value
+  //
+  *pValue = Value;
+
+  //
+  //  Return the conversion status
+  //
+  return Status;
+}
+
+
+/**
+  Process the TFTP request
+
+  @param [in] pTftpServer The TFTP server control structure address.
+  @param [in] pContext    Connection context structure address
+
+**/
+VOID
+TftpProcessRequest (
+  IN TSDT_TFTP_SERVER * pTftpServer,
+  IN TSDT_CONNECTION_CONTEXT * pContext
+  )
+{
+  BOOLEAN bCloseContext;
+  BOOLEAN bIgnorePacket;
+  UINT16 BlockNumber;
+  UINT16 Opcode;
+  UINT8 * pBuffer;
+  UINT8 * pEnd;
+  UINT8 * pFileName;
+  UINT8 * pMode;
+  UINT8 * pOption;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Get the opcode
+  //
+  pBuffer = &pTftpServer->RxBuffer[0];
+  Opcode = HTONS ( *(UINT16 *)&pBuffer[0]);
+Print ( L"TFTP Opcode: 0x%08x\r\n", Opcode );
+
+  //
+  //  Validate the parameters
+  //
+  bCloseContext = FALSE;
+  bIgnorePacket = FALSE;
+  switch ( Opcode ) {
+  default:
+    DEBUG (( DEBUG_TFTP_REQUEST,
+              "ERROR - Unknown TFTP opcode: %d\r\n",
+              Opcode ));
+    bIgnorePacket = TRUE;
+    break;
+
+  case TFTP_OP_READ_REQUEST:
+    break;
+
+  case TFTP_OP_DATA:
+    if ( NULL == pContext ) {
+      DEBUG (( DEBUG_ERROR,
+                "ERROR - File not open for %d.%d.%d.%d:%d\r\n",
+                (UINT8)pTftpServer->RemoteAddress.sin_addr.s_addr,
+                (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 8 ),
+                (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 16 ),
+                (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 24 ),
+                htons ( pTftpServer->RemoteAddress.sin_port )));
+      bIgnorePacket = TRUE;
+      break;
+    }
+    if ( pContext->bExpectAck ) {
+      DEBUG (( DEBUG_ERROR,
+                "ERROR - Expecting ACKs not data for pContext 0x%08x\r\n",
+                pContext ));
+      bIgnorePacket = TRUE;
+      break;
+    }
+    if ( pTftpServer->RxBytes > (ssize_t)( pContext->BlockSize + 2 + 2 ))
+    {
+      DEBUG (( DEBUG_ERROR,
+                "ERROR - Receive data length of %d > %d bytes (maximum block size) for pContext 0x%08x\r\n",
+                pTftpServer->RxBytes - 2 - 2,
+                pContext->BlockSize,
+                pContext ));
+      bIgnorePacket = TRUE;
+      break;
+    }
+    break;
+
+  case TFTP_OP_ACK:
+    if ( NULL == pContext ) {
+      DEBUG (( DEBUG_ERROR,
+                "ERROR - File not open for %d.%d.%d.%d:%d\r\n",
+                (UINT8)pTftpServer->RemoteAddress.sin_addr.s_addr,
+                (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 8 ),
+                (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 16 ),
+                (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 24 ),
+                htons ( pTftpServer->RemoteAddress.sin_port )));
+      bIgnorePacket = TRUE;
+    }
+    if ( !pContext->bExpectAck ) {
+      DEBUG (( DEBUG_ERROR,
+                "ERROR - Expecting data not ACKs for pContext 0x%08x\r\n",
+                pContext ));
+      bIgnorePacket = TRUE;
+      break;
+    }
+    break;
+
+  case TFTP_OP_ERROR:
+    if ( NULL == pContext ) {
+      DEBUG (( DEBUG_ERROR,
+                "ERROR - File not open for %d.%d.%d.%d:%d\r\n",
+                (UINT8)pTftpServer->RemoteAddress.sin_addr.s_addr,
+                (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 8 ),
+                (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 16 ),
+                (UINT8)( pTftpServer->RemoteAddress.sin_addr.s_addr >> 24 ),
+                htons ( pTftpServer->RemoteAddress.sin_port )));
+      bIgnorePacket = TRUE;
+    }
+    break;
+  }
+  if ( !bIgnorePacket ) {
+    //
+    //  Process the request
+    //
+    switch ( Opcode ) {
+    default:
+      DEBUG (( DEBUG_TFTP_REQUEST,
+                "ERROR - Unable to process TFTP opcode: %d\r\n",
+                Opcode ));
+      break;
+
+    case TFTP_OP_READ_REQUEST:
+
+      //
+      //  Close the context if necessary
+      //
+      if ( NULL != pContext ) {
+        ContextRemove ( pTftpServer, pContext );
+      }
+
+      //
+      //  Create the connection context
+      //
+      pContext = ContextAdd ( pTftpServer );
+      if ( NULL == pContext ) {
+        break;
+      }
+
+      //
+      //  Locate the mode
+      //
+      pFileName = &pBuffer[2];
+      pEnd = &pBuffer[pTftpServer->RxBytes];
+      pMode = pFileName;
+      while (( pEnd > pMode ) && ( 0 != *pMode )) {
+        pMode += 1;
+      }
+      if ( pEnd <= pMode ) {
+        //
+        //  Mode not found
+        //
+        DEBUG (( DEBUG_ERROR | DEBUG_RX,
+                  "ERROR - File mode not found\r\n" ));
+        //
+        //  Tell the client of the error
+        //
+        TftpSendError ( pTftpServer,
+                        pContext,
+                        0,
+                        (UINT8 *)"File open mode not found" );
+        break;
+      }
+      pMode += 1;
+      DEBUG (( DEBUG_TFTP_REQUEST,
+                "TFTP - FileName: %a\n",
+                pFileName ));
+
+      //
+      //  Locate the options
+      //
+      pOption = pMode;
+      while (( pEnd > pOption ) && ( 0 != *pOption )) {
+        pOption += 1;
+      }
+      if ( pEnd <= pOption ) {
+        //
+        //  End of mode not found
+        //
+        DEBUG (( DEBUG_ERROR | DEBUG_RX,
+                  "ERROR - File mode not valid\r\n" ));
+        //
+        //  Tell the client of the error
+        //
+        TftpSendError ( pTftpServer,
+                        pContext,
+                        0,
+                        (UINT8 *)"File open mode not valid" );
+        break;
+      }
+      pOption += 1;
+      DEBUG (( DEBUG_TFTP_REQUEST,
+                "TFTP - Mode: %a\r\n",
+                pMode ));
+
+      //
+      //  Verify the mode is supported
+      //
+      if ( 0 != stricmp ((char *)pMode, "octet" )) {
+        //
+        //  File access mode not supported
+        //
+        DEBUG (( DEBUG_ERROR | DEBUG_TFTP_REQUEST,
+                  "ERROR - File mode %a not supported\r\n",
+                  pMode ));
+
+        //
+        //  Tell the client of the error
+        //
+        TftpSendError ( pTftpServer,
+                        pContext,
+                        0,
+                        (UINT8 *)"File open mode not supported" );
+        break;
+      }
+
+      //
+      //  Open the file, close the context on error
+      //
+// TODO: Remove the following line
+pContext->File = (EFI_HANDLE)1;
+
+      //
+      //  Determine the file length
+      //
+//fstat
+
+      //
+      //  Process the options
+      //
+      TftpOptions ( pContext, pOption, pEnd );
+
+      //
+      //  Read in the first portion of the file
+      //
+
+      //
+      //  Send the first block
+      //
+      pContext->bExpectAck = TRUE;
+      if ( 2 < pContext->TxBytes ) {
+        //
+        //  Send the OACK
+        //
+        Status = TftpTxPacket ( pTftpServer, pContext );
+      }
+      else {
+        //
+        //  Send the first block of data
+        //
+        Status = TftpSendNextBlock ( pTftpServer, pContext );
+      }
+      break;
+
+    case TFTP_OP_ACK:
+      //
+      //  Get the block number that is being ACKed
+      //
+      BlockNumber = pTftpServer->RxBuffer[2];
+      BlockNumber <<= 8;
+      BlockNumber |= pTftpServer->RxBuffer[3];
+
+      //
+      //  Determine if this is the correct ACK
+      //
+      DEBUG (( DEBUG_TFTP_ACK,
+                "ACK for block 0x%04x received\r\n",
+                BlockNumber ));
+      if (( !pContext->bExpectAck )
+        || ( BlockNumber != pContext->AckNext ))
+      {
+        DEBUG (( DEBUG_WARN | DEBUG_TFTP_ACK,
+                  "WARNING - Expecting ACK 0x%0x4 not received ACK 0x%08x\r\n",
+                  pContext->AckNext,
+                  BlockNumber ));
+      }
+      else {
+        //
+        //  Process the expected ACK
+        //
+        if ( pContext->bEofSent ) {
+          bCloseContext = TRUE;
+        }
+        else {
+          //
+          //  Set the next expected ACK
+          //
+          pContext->AckNext += 1;
+
+          //
+          //  Send the next packet of data
+          //
+          Status = TftpSendNextBlock ( pTftpServer, pContext );
+        }
+      }
+      break;
+    }
+  }
+
+  //
+  //  Determine if the context should be closed
+  //
+  if ( bCloseContext ) {
+    ContextRemove ( pTftpServer, pContext );
+  }
+
+  DBG_EXIT ( );
+}
+
+
+/**
+  Build and send an error packet
+
+  @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
+
+  @retval EFI_SUCCESS     Message processed successfully
+
+**/
+EFI_STATUS
+TftpSendError (
+  IN TSDT_TFTP_SERVER * pTftpServer,
+  IN TSDT_CONNECTION_CONTEXT * pContext,
+  IN UINT16 Error,
+  IN UINT8 * pError
+  )
+{
+  UINT8 Character;
+  UINT8 * pBuffer;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Build the error packet
+  //
+  pBuffer = &pContext->TxBuffer[0];
+  pBuffer[0] = 0;
+  pBuffer[1] = TFTP_OP_ERROR;
+  pBuffer[2] = (UINT8)( Error >> 8 );
+  pBuffer[3] = (UINT8)Error;
+
+  //
+  //  Copy the zero terminated string into the buffer
+  //
+  pBuffer += 4;
+  do {
+    Character = *pError++;
+    *pBuffer++ = Character;
+  } while ( 0 != Character );
+
+  //
+  //  Send the error message
+  //
+  pContext->TxBytes = pBuffer - &pContext->TxBuffer[0];
+  Status = TftpTxPacket ( pTftpServer, pContext );
+
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Send the next block of file system data
+
+  @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
+  )
+{
+  ssize_t LengthInBytes;
+  UINT8 * pBuffer;
+  EFI_STATUS Status;
+
+  //
+  //  Determine how much data needs to be sent
+  //
+  LengthInBytes = pContext->BlockSize;
+  if (( pContext->LengthInBytes < TFTP_MAX_BLOCK_SIZE )
+    || ( LengthInBytes > (ssize_t)pContext->LengthInBytes )) {
+    LengthInBytes = (ssize_t)pContext->LengthInBytes;
+    pContext->bEofSent = TRUE;
+  }
+
+  //
+  //  Set the TFTP opcode and block number
+  //
+  pBuffer = &pContext->TxBuffer[0];
+  *pBuffer++ = 0;
+  *pBuffer++ = TFTP_OP_DATA;
+  *pBuffer++ = (UINT8)( pContext->AckNext >> 8 );
+  *pBuffer++ = (UINT8)pContext->AckNext;
+
+  //
+  //  Copy the file data into the transmit buffer
+  //
+  pContext->TxBytes = 2 + 2 + LengthInBytes;
+  if ( 0 < LengthInBytes ) {
+    CopyMem ( &pBuffer,
+              pContext->pBuffer,
+              LengthInBytes );
+  }
+
+  //
+  //  Send the next block
+  //
+  Status = TftpTxPacket ( pTftpServer, pContext );
+
+  //
+  //  Return the operation status
+  //
+  return Status;
+}
+
+
+/**
+  Create the port for the TFTP server
+
+  This routine polls the network layer to create the TFTP port for the
+  TFTP 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.
+
+  @param [in] pTftpServer  The TFTP server control structure address.
+
+**/
+VOID
+TftpServerTimer (
+  IN TSDT_TFTP_SERVER * pTftpServer
+  )
+{
+  UINT16 TftpPort;
+  int SocketStatus;
+  EFI_STATUS Status;
+
+  DEBUG (( DEBUG_SERVER_TIMER, "Entering TftpServerTimer\r\n" ));
+
+  //
+  //  Open the TFTP port on the server
+  //
+  do {
+    do {
+      //
+      //  Wait for a while
+      //
+      Status = gBS->CheckEvent ( pTftpServer->TimerEvent );
+    } while ( EFI_SUCCESS != Status );
+
+    //
+    //  Attempt to create the socket for the TFTP server
+    //
+    pTftpServer->TftpPort.events = POLLRDNORM | POLLHUP;
+    pTftpServer->TftpPort.revents = 0;
+    pTftpServer->TftpPort.fd = socket ( AF_INET,
+                                        SOCK_DGRAM,
+                                        IPPROTO_UDP );
+    if ( -1 != pTftpServer->TftpPort.fd )
+    {
+      //
+      //  Set the socket address
+      //
+      ZeroMem ( &pTftpServer->TftpServerAddress,
+                sizeof ( pTftpServer->TftpServerAddress ));
+      TftpPort = 69;
+      DEBUG (( DEBUG_TFTP_PORT,
+                "TFTP Port: %d\r\n",
+                TftpPort ));
+      pTftpServer->TftpServerAddress.sin_len = sizeof ( pTftpServer->TftpServerAddress );
+      pTftpServer->TftpServerAddress.sin_family = AF_INET;
+      pTftpServer->TftpServerAddress.sin_addr.s_addr = INADDR_ANY;
+      pTftpServer->TftpServerAddress.sin_port = htons ( TftpPort );
+
+      //
+      //  Bind the socket to the TFTP port
+      //
+      SocketStatus = bind ( pTftpServer->TftpPort.fd,
+                            (struct sockaddr *) &pTftpServer->TftpServerAddress,
+                            pTftpServer->TftpServerAddress.sin_len );
+      if ( -1 != SocketStatus ) {
+        DEBUG (( DEBUG_TFTP_PORT,
+                  "0x%08x: Socket bound to port %d\r\n",
+                  pTftpServer->TftpPort.fd,
+                  TftpPort ));
+      }
+
+      //
+      //  Release the socket if necessary
+      //
+      if ( -1 == SocketStatus ) {
+        close ( pTftpServer->TftpPort.fd );
+        pTftpServer->TftpPort.fd = -1;
+      }
+    }
+
+    //
+    //  Wait until the socket is open
+    //
+  }while ( -1 == pTftpServer->TftpPort.fd );
+
+  DEBUG (( DEBUG_SERVER_TIMER, "Exiting TftpServerTimer\r\n" ));
+}
+
+
+/**
+  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
+  )
+{
+  EFI_STATUS Status;
+  UINT64 TriggerTime;
+
+  DBG_ENTER ( );
+
+  //
+  //  Assume the timer is already running
+  //
+  Status = EFI_ALREADY_STARTED;
+  if ( !pTftpServer->bTimerRunning ) {
+    //
+    //  Compute the poll interval
+    //
+    TriggerTime = TFTP_PORT_POLL_DELAY * ( 1000 * 10 );
+    Status = gBS->SetTimer ( pTftpServer->TimerEvent,
+                             TimerPeriodic,
+                             TriggerTime );
+    if ( !EFI_ERROR ( Status )) {
+      DEBUG (( DEBUG_TFTP_PORT, "TFTP port timer started\r\n" ));
+
+      //
+      //  Mark the timer running
+      //
+      pTftpServer->bTimerRunning = TRUE;
+    }
+    else {
+      DEBUG (( DEBUG_ERROR | DEBUG_TFTP_PORT,
+                "ERROR - Failed to start TFTP port timer, Status: %r\r\n",
+                Status ));
+    }
+  }
+
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  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
+  )
+{
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Assume the timer is stopped
+  //
+  Status = EFI_SUCCESS;
+  if ( pTftpServer->bTimerRunning ) {
+    //
+    //  Stop the port creation polling
+    //
+    Status = gBS->SetTimer ( pTftpServer->TimerEvent,
+                             TimerCancel,
+                             0 );
+    if ( !EFI_ERROR ( Status )) {
+      DEBUG (( DEBUG_TFTP_PORT, "TFT[ port timer stopped\r\n" ));
+
+      //
+      //  Mark the timer stopped
+      //
+      pTftpServer->bTimerRunning = FALSE;
+    }
+    else {
+      DEBUG (( DEBUG_ERROR | DEBUG_TFTP_PORT,
+                "ERROR - Failed to stop TFT[ port timer, Status: %r\r\n",
+                Status ));
+    }
+  }
+
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+/**
+  Send the next TFTP packet
+
+  @param [in] pTftpServer   The TFTP server control structure address.
+  @param [in] pContext      The context structure address.
+
+  @retval EFI_SUCCESS   Message processed successfully
+
+**/
+EFI_STATUS
+TftpTxPacket (
+  IN TSDT_TFTP_SERVER * pTftpServer,
+  IN TSDT_CONNECTION_CONTEXT * pContext
+  )
+{
+  ssize_t LengthInBytes;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Assume success
+  //
+  Status = EFI_SUCCESS;
+
+  //
+  //  Send the TFTP packet
+  //
+  DEBUG (( DEBUG_TX,
+            "0x%08x: pContext sending 0x%08x bytes\r\n",
+            pContext,
+            pContext->TxBytes ));
+  LengthInBytes = sendto ( pTftpServer->TftpPort.fd,
+                           &pContext->TxBuffer[0],
+                           pContext->TxBytes,
+                           0,
+                           (struct sockaddr *)&pContext->RemoteAddress,
+                           pContext->RemoteAddress.sin_len );
+  if ( -1 == LengthInBytes ) {
+    DEBUG (( DEBUG_ERROR | DEBUG_TX,
+              "ERROR - Transmit failure, errno: 0x%08x\r\n",
+              errno ));
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Entry point for the TFTP server application.
+
+  @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
+  )
+{
+  TSDT_TFTP_SERVER * pTftpServer;
+  EFI_STATUS Status;
+
+  //
+  //  Create a timer event to start TFTP port
+  //
+  pTftpServer = &mTftpServer;
+  Status = gBS->CreateEvent ( EVT_TIMER,
+                              TPL_TFTP_SERVER,
+                              NULL,
+                              NULL,
+                              &pTftpServer->TimerEvent );
+  if ( !EFI_ERROR ( Status )) {
+    Status = TftpServerTimerStart ( pTftpServer );
+    if ( !EFI_ERROR ( Status )) {
+      //
+      //  Run the TFTP server forever
+      //
+      for ( ; ; ) {
+        //
+        //  Poll the network layer to create the TFTP port
+        //  for the tftp 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.
+        //
+        TftpServerTimer ( pTftpServer );
+
+        //
+        //  Poll the socket for activity
+        //
+        do {
+          SocketPoll ( pTftpServer );
+        } while ( -1 != pTftpServer->TftpPort.fd );
+
+//
+// TODO: Remove the following test code
+//  Exit when the network connection is broken
+//
+break;
+      }
+
+      //
+      //  Done with the timer event
+      //
+      TftpServerTimerStop ( pTftpServer );
+      Status = gBS->CloseEvent ( pTftpServer->TimerEvent );
+    }
+  }
+
+  //
+  //  Return the final status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/AppPkg/Applications/Sockets/TftpServer/TftpServer.h b/AppPkg/Applications/Sockets/TftpServer/TftpServer.h
new file mode 100644 (file)
index 0000000..e56d21b
--- /dev/null
@@ -0,0 +1,331 @@
+/** @file\r
+  Definitions for the TFTP server.\r
+\r
+  Copyright (c) 2011, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _TFTP_SERVER_H_\r
+#define _TFTP_SERVER_H_\r
+\r
+#include <errno.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <Uefi.h>\r
+\r
+#include <Guid/EventGroup.h>\r
+\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/UefiApplicationEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Protocol/BlockIo.h>\r
+\r
+#include <netinet/in.h>\r
+\r
+#include <sys/EfiSysCall.h>\r
+#include <sys/poll.h>\r
+#include <sys/socket.h>\r
+\r
+//------------------------------------------------------------------------------\r
+//  Macros\r
+//------------------------------------------------------------------------------\r
+\r
+#if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics. */\r
+#define DBG_ENTER()             DEBUG (( DEBUG_INFO, "Entering " __FUNCTION__ "\n" )) ///<  Display routine entry\r
+#define DBG_EXIT()              DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ "\n" ))  ///<  Display routine exit\r
+#define DBG_EXIT_DEC(Status)    DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %d\n", Status ))      ///<  Display routine exit with decimal value\r
+#define DBG_EXIT_HEX(Status)    DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status ))  ///<  Display routine exit with hex value\r
+#define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %r\n", Status ))      ///<  Display routine exit with status value\r
+#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\r
+#else   //  _MSC_VER\r
+#define DBG_ENTER()\r
+#define DBG_EXIT()\r
+#define DBG_EXIT_DEC(Status)\r
+#define DBG_EXIT_HEX(Status)\r
+#define DBG_EXIT_STATUS(Status)\r
+#define DBG_EXIT_TF(Status)\r
+#endif  //  _MSC_VER\r
+\r
+#define DIM(x)    ( sizeof ( x ) / sizeof ( x[0] ))   ///<  Compute the number of entries in an array\r
+\r
+//------------------------------------------------------------------------------\r
+//  Constants\r
+//------------------------------------------------------------------------------\r
+\r
+#define DEBUG_SOCKET_POLL       0x40000000  ///<  Display the socket poll messages\r
+#define DEBUG_PORT_WORK         0x20000000  ///<  Display the port work messages\r
+#define DEBUG_SERVER_TIMER      0x10000000  ///<  Display the socket poll messages\r
+#define DEBUG_TFTP_PORT         0x08000000  ///<  Display the TFTP port messages\r
+#define DEBUG_TFTP_REQUEST      0x04000000  ///<  Display the TFTP request messages\r
+#define DEBUG_TX                0x02000000  ///<  Display transmit messages\r
+#define DEBUG_RX                0x01000000  ///<  Display receive messages\r
+#define DEBUG_TFTP_ACK          0x00800000  ///<  Display the TFTP ACK messages\r
+\r
+#define TFTP_PORT_POLL_DELAY  ( 2 * 1000 )  ///<  Delay in milliseconds for attempts to open the TFTP port\r
+#define CLIENT_POLL_DELAY     50            ///<  Delay in milliseconds between client polls\r
+\r
+#define TPL_TFTP_SERVER        TPL_CALLBACK ///<  TPL for routine synchronization\r
+\r
+/**\r
+  Verify new TPL value\r
+\r
+  This macro which is enabled when debug is enabled verifies that\r
+  the new TPL value is >= the current TPL value.\r
+**/\r
+#ifdef VERIFY_TPL\r
+#undef VERIFY_TPL\r
+#endif  //  VERIFY_TPL\r
+\r
+#if !defined(MDEPKG_NDEBUG)\r
+\r
+#define VERIFY_TPL(tpl)                           \\r
+{                                                 \\r
+  EFI_TPL PreviousTpl;                            \\r
+                                                  \\r
+  PreviousTpl = gBS->RaiseTPL ( TPL_HIGH_LEVEL ); \\r
+  gBS->RestoreTPL ( PreviousTpl );                \\r
+  if ( PreviousTpl > tpl ) {                      \\r
+    DEBUG (( DEBUG_ERROR, "Current TPL: %d, New TPL: %d\r\n", PreviousTpl, tpl ));  \\r
+    ASSERT ( PreviousTpl <= tpl );                \\r
+  }                                               \\r
+}\r
+\r
+#else   //  MDEPKG_NDEBUG\r
+\r
+#define VERIFY_TPL(tpl)\r
+\r
+#endif  //  MDEPKG_NDEBUG\r
+\r
+#define TFTP_SERVER_SIGNATURE       SIGNATURE_32('T','F','T','P') ///<  TSDT_TFTP_SERVER memory signature\r
+\r
+//\r
+//  See: http://www.rfc-editor.org/rfc/pdfrfc/rfc1350.txt.pdf\r
+//\r
+//  TFTP Operations\r
+//\r
+\r
+#define TFTP_OP_READ_REQUEST      1     ///<  Read request, zero terminated file name, zero terminated mode\r
+#define TFTP_OP_WRITE_REQUEST     2     ///<  Write request, zero terminated file name, zero terminated mode\r
+#define TFTP_OP_DATA              3     ///<  Data block, end-of-file indicated by short block\r
+#define TFTP_OP_ACK               4     ///<  ACK block number\r
+#define TFTP_OP_ERROR             5     ///<  Error number and explaination\r
+#define TFTP_OP_OACK              6     ///<  ACK the options\r
+\r
+#define TFTP_MAX_BLOCK_SIZE       4096  ///<  Maximum block size\r
+\r
+//------------------------------------------------------------------------------\r
+//  Data Types\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+  Port control structure\r
+**/\r
+typedef struct _TSDT_CONNECTION_CONTEXT TSDT_CONNECTION_CONTEXT;\r
+typedef struct _TSDT_CONNECTION_CONTEXT {\r
+  //\r
+  //  Remote connection management\r
+  //\r
+  TSDT_CONNECTION_CONTEXT * pNext;  ///<  Next context in the connection list\r
+  struct sockaddr_in RemoteAddress; ///<  Remote address\r
+\r
+  //\r
+  //  TFTP management parameters\r
+  //\r
+  UINT16 AckNext;               ///<  Next block to be received\r
+  BOOLEAN bExpectAck;           ///<  TRUE for read, FALSE for write\r
+  UINT32 BlockSize;             ///<  Negotiated block size\r
+  UINT32 Timeout;               ///<  Number of seconds to wait before retransmission\r
+\r
+  //\r
+  //  File management parameters\r
+  //\r
+  EFI_HANDLE File;              ///<  NULL while file is closed\r
+  UINT64 LengthInBytes;         ///<  Size of the file\r
+  UINT64 MaxTransferSize;       ///<  Maximum transfer size\r
+  BOOLEAN bEofSent;             ///<  End of file sent\r
+  UINT8 * pBuffer;              ///<  Pointer into the file data\r
+  UINT8 * pEnd;                 ///<  End of the file data\r
+  UINT8 FileData [ 64 * TFTP_MAX_BLOCK_SIZE ];  ///<  File data to send\r
+\r
+  //\r
+  //  Buffer management\r
+  //\r
+  ssize_t   TxBytes;            ///<  Bytes in the TX buffer\r
+  UINT8     TxBuffer [ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///<  Transmit buffer\r
+}GCC_TSDT_CONNECTION_CONTEXT;\r
+\r
+/**\r
+  TFTP server control structure\r
+**/\r
+typedef struct {\r
+  UINTN Signature;              ///<  Structure identification\r
+\r
+  //\r
+  //  Image attributes\r
+  //\r
+  EFI_HANDLE ImageHandle;       ///<  Image handle\r
+\r
+  //\r
+  //  TFTP port management\r
+  //\r
+  BOOLEAN   bTimerRunning;      ///<  Port creation timer status\r
+  EFI_EVENT TimerEvent;         ///<  Timer to open TFTP port\r
+  struct pollfd TftpPort;       ///<  Poll descriptor for the TFTP port\r
+  struct sockaddr_in TftpServerAddress; ///<  Address of the local TFTP server\r
+\r
+  //\r
+  //  Request management\r
+  //\r
+  struct sockaddr_in RemoteAddress; ///<  Remote address\r
+  ssize_t   RxBytes;                ///<  Receive data length in bytes\r
+  UINT8     RxBuffer [ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///<  Receive buffer\r
+\r
+  //\r
+  //  Client port management\r
+  //\r
+  TSDT_CONNECTION_CONTEXT * pContextList; ///<  List of connection context structures\r
+} TSDT_TFTP_SERVER;\r
+\r
+//#define SERVER_FROM_SERVICE(a) CR(a, TSDT_TFTP_SERVER, ServiceBinding, TFTP_SERVER_SIGNATURE) ///< Locate DT_LAYER from service binding\r
+\r
+extern TSDT_TFTP_SERVER mTftpServer;\r
+\r
+//------------------------------------------------------------------------------\r
+// Support routines\r
+//------------------------------------------------------------------------------\r
+\r
+/**\r
+  Process the TFTP request\r
+\r
+  @param [in] pOption   Address of the first zero terminated option string\r
+  @param [in] pValue    Address to receive the value\r
+\r
+  @retval EFI_SUCCESS   Option translated into a value\r
+\r
+**/\r
+EFI_STATUS\r
+TftpOptionValue (\r
+  IN UINT8 * pOption,\r
+  IN INT32 * pValue\r
+  );\r
+\r
+/**\r
+  Process the TFTP request\r
+\r
+  @param [in] pTftpServer The TFTP server control structure address.\r
+  @param [in] pContext    Connection context structure address\r
+\r
+**/\r
+VOID\r
+TftpProcessRequest (\r
+  IN TSDT_TFTP_SERVER * pTftpServer,\r
+  IN TSDT_CONNECTION_CONTEXT * pContext\r
+  );\r
+\r
+/**\r
+  Build and send an error packet\r
+\r
+  @param [in] pTftpServer The TFTP server control structure address.\r
+  @param [in] pContext    The context structure address.\r
+  @param [in] Error       Error number for the packet\r
+  @param [in] pError      Zero terminated error string address\r
+\r
+  @retval EFI_SUCCESS     Message processed successfully\r
+\r
+**/\r
+EFI_STATUS\r
+TftpSendError (\r
+  IN TSDT_TFTP_SERVER * pTftpServer,\r
+  IN TSDT_CONNECTION_CONTEXT * pContext,\r
+  IN UINT16 Error,\r
+  IN UINT8 * pError\r
+  );\r
+\r
+/**\r
+  Send the next block of file system data\r
+\r
+  @param [in] pTftpServer The TFTP server control structure address.\r
+  @param [in] pContext    The context structure address.\r
+\r
+  @retval EFI_SUCCESS   Message processed successfully\r
+\r
+**/\r
+EFI_STATUS\r
+TftpSendNextBlock (\r
+  IN TSDT_TFTP_SERVER * pTftpServer,\r
+  IN TSDT_CONNECTION_CONTEXT * pContext\r
+  );\r
+\r
+/**\r
+  TFTP port creation timer routine\r
+\r
+  This routine polls the socket layer waiting for the initial network connection\r
+  which will enable the creation of the TFTP port.  The socket layer will manage\r
+  the coming and going of the network connections after that until the last network\r
+  connection is broken.\r
+\r
+  @param [in] pTftpServer  The TFTP server control structure address.\r
+\r
+**/\r
+VOID\r
+TftpServerTimer (\r
+  IN TSDT_TFTP_SERVER * pTftpServer\r
+  );\r
+\r
+/**\r
+  Start the TFTP server port creation timer\r
+\r
+  @param [in] pTftpServer  The TFTP server control structure address.\r
+\r
+  @retval EFI_SUCCESS         The timer was successfully started.\r
+  @retval EFI_ALREADY_STARTED The timer is already running.\r
+  @retval Other               The timer failed to start.\r
+\r
+**/\r
+EFI_STATUS\r
+TftpServerTimerStart (\r
+  IN TSDT_TFTP_SERVER * pTftpServer\r
+  );\r
+\r
+/**\r
+  Stop the TFTP server port creation timer\r
+\r
+  @param [in] pTftpServer  The TFTP server control structure address.\r
+\r
+  @retval EFI_SUCCESS   The TFTP port timer is stopped\r
+  @retval Other         Failed to stop the TFTP port timer\r
+\r
+**/\r
+EFI_STATUS\r
+TftpServerTimerStop (\r
+  IN TSDT_TFTP_SERVER * pTftpServer\r
+  );\r
+\r
+/**\r
+  Send the next TFTP packet\r
+\r
+  @param [in] pTftpServer   The TFTP server control structure address.\r
+  @param [in] pContext      The context structure address.\r
+\r
+  @retval EFI_SUCCESS   Message processed successfully\r
+\r
+**/\r
+EFI_STATUS\r
+TftpTxPacket (\r
+  IN TSDT_TFTP_SERVER * pTftpServer,\r
+  IN TSDT_CONNECTION_CONTEXT * pContext\r
+  );\r
+\r
+//------------------------------------------------------------------------------\r
+\r
+#endif  //  _TFTP_SERVER_H_\r
diff --git a/AppPkg/Applications/Sockets/TftpServer/TftpServer.inf b/AppPkg/Applications/Sockets/TftpServer/TftpServer.inf
new file mode 100644 (file)
index 0000000..f487242
--- /dev/null
@@ -0,0 +1,66 @@
+#/** @file\r
+#  TFTP Server Application\r
+#\r
+# This file contains an 'Intel Peripheral Driver' and is      \r
+# licensed for Intel CPUs and chipsets under the terms of your\r
+# license agreement with Intel or your vendor.  This file may \r
+# be modified by the user, subject to additional terms of the \r
+# license agreement                                           \r
+#\r
+#\r
+# Copyright (c)  20011 Intel Corporation. All rights reserved\r
+# This software and associated documentation (if any) is furnished\r
+# under a license and may only be used or copied in accordance\r
+# with the terms of the license. Except as permitted by such\r
+# license, no part of this software or documentation may be\r
+# reproduced, stored in a retrieval system, or transmitted in any\r
+# form or by any means without the express written consent of\r
+# Intel Corporation.\r
+#\r
+##\r
+\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = TftpServer\r
+  FILE_GUID                      = 94621F9E-B5CA-4cfd-82BE-0C542EB0D9BE\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = ShellCEntryLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  TftpServer.h\r
+  TftpServer.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  StdLib/StdLib.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseMemoryLib\r
+  BsdSocketLib\r
+  DebugLib\r
+  DevShell\r
+  EfiSocketLib\r
+  LibC\r
+  ShellLib\r
+  ShellCEntryLib\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+  UefiRuntimeServicesTableLib\r
+#  UseSocketDxe\r
+\r
+[BuildOptions]\r
+  INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186\r
+   MSFT:*_*_*_CC_FLAGS = /Od\r
+    GCC:*_*_*_CC_FLAGS = -O0 -Wno-unused-variable\r
+\r
diff --git a/AppPkg/Applications/Sockets/WebServer/ACPI.c b/AppPkg/Applications/Sockets/WebServer/ACPI.c
new file mode 100644 (file)
index 0000000..a7da233
--- /dev/null
@@ -0,0 +1,1918 @@
+/*++
+  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
+  Display the runtime services table
+
+**/
+
+#include <WebServer.h>
+#include <Guid/Acpi.h>
+#include <IndustryStandard/Acpi10.h>
+#include <IndustryStandard/Acpi30.h>
+
+#pragma warning ( disable : 4305 )
+
+//
+// Ensure proper structure formats
+//
+#pragma pack(1)
+
+typedef struct {
+  UINT8 AddressSpaceId;
+  UINT8 RegisterBitWidth;
+  UINT8 RegisterBitOffset;
+  UINT8 AccessSize;
+  UINT64 Address;
+} GENERIC_ADDRESS;
+
+
+typedef struct {
+  UINT32 Signature;           //    0
+  UINT32 Length;              //    4
+  UINT8 Revision;             //    8
+  UINT8 Checksum;             //    9
+  UINT8 OemId[6];             //   10
+  UINT8 OemTableId[8];        //   16
+  UINT32 OemRevision;         //   24
+  UINT32 CreatorId;           //   28
+  UINT32 CreatorRevision;     //   32
+  UINT8 DefinitionBlock[1];   //   36
+} ACPI_DSDT;
+
+
+typedef struct {
+  UINT32 Signature;           //    0
+  UINT32 Length;              //    4
+  UINT8 Revision;             //    8
+  UINT8 Checksum;             //    9
+  UINT8 OemId[6];             //   10
+  UINT8 OemTableId[8];        //   16
+  UINT32 OemRevision;         //   24
+  UINT32 CreatorId;           //   28
+  UINT32 CreatorRevision;     //   32
+  UINT32 FirmwareCtrl;        //   36
+  UINT32 DSDT;                //   40
+  UINT8 Reserved;             //   44
+  UINT8 PreferredPmProfile;   //   45
+  UINT16 SciInt;              //   46
+  UINT32 SmiCmd;              //   48
+  UINT8 AcpiEnable;           //   52
+  UINT8 AcpiDisable;          //   53
+  UINT8 S4BiosReq;            //   54
+  UINT8 PStateCnt;            //   55
+  UINT32 Pm1aEvtBlk;          //   56
+  UINT32 Pm1bEvtBlk;          //   60
+  UINT32 Pm1aCntBlk;          //   64
+  UINT32 Pm1bCntBlk;          //   68
+  UINT32 Pm2CntBlk;           //   72
+  UINT32 PmTmrBlk;            //   76
+  UINT32 Gpe0Blk;             //   80
+  UINT32 Gpe1Blk;             //   84
+  UINT8 Pm1EvtLen;            //   88
+  UINT8 Pm1CntLen;            //   89
+  UINT8 PM2CntLen;            //   90
+  UINT8 PmTmrLen;             //   91
+  UINT8 Gpe0BlkLen;           //   92
+  UINT8 Gpe1BlkLen;           //   93
+  UINT8 Gpe1Base;             //   94
+  UINT8 CstCnt;               //   95
+  UINT16 PLvl2Lat;            //   96
+  UINT16 PLvl3Lat;            //   98
+  UINT16 FlushSize;           //  100
+  UINT16 FlushStride;         //  102
+  UINT8 DutyOffset;           //  104
+  UINT8 DutyWidth;            //  105
+  UINT8 DayAlrm;              //  106
+  UINT8 MonAlrm;              //  107
+  UINT8 Century;              //  108
+  UINT16 IapcBootArch;        //  109
+  UINT8 Reserved2;            //  111
+  UINT32 Flags;               //  112
+  UINT32 ResetReg [3];        //  116
+  UINT8 ResetValue;           //  128
+  UINT8 Reserved3 [3];        //  129
+  UINT64 XFirmwareCtrl;       //  132
+  UINT64 XDsdt;               //  140
+  UINT32 XPm1aEvtBlk [3];     //  148
+  UINT32 XPm1bEvtBlk [3];     //  160
+  UINT32 XPm1aCntBlk [3];     //  172
+  UINT32 XPm1bCntBlk [3];     //  184
+  UINT32 XPm2CntBlk [3];      //  196
+  UINT32 XPmTmrBlk [3];       //  208
+  UINT32 XGpe0Blk [3];        //  220
+  UINT32 XGpe1Blk [3];        //  232
+} ACPI_FADT;
+
+
+typedef struct {
+  UINT32 Signature;
+  UINT32 Length;
+  UINT8 Revision;
+  UINT8 Checksum;
+  UINT8 OemId[6];
+  UINT8 OemTableId[8];
+  UINT32 OemRevision;
+  UINT32 CreatorId;
+  UINT32 CreatorRevision;
+  UINT32 Entry[1];
+} ACPI_RSDT;
+
+
+#pragma pack()
+
+
+typedef struct {
+  UINT32 Signature;
+  CONST CHAR8 * pTableName;
+  CONST CHAR16 * pWebPage;
+} TABLE_SIGNATURE;
+
+
+CONST TABLE_SIGNATURE mTableId [] = {
+  { DSDT_SIGNATURE, "DSDT", PAGE_ACPI_DSDT },
+  { FADT_SIGNATURE, "FADT", PAGE_ACPI_FADT }
+};
+
+
+/**
+  Locate the RSDT table
+
+  @returns Table address or NULL if not found
+
+**/
+CONST ACPI_RSDT *
+LocateRsdt (
+  VOID
+  )
+{
+  CONST EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp10b;
+  CONST EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp30;
+  CONST ACPI_RSDT * pRsdt;
+  EFI_STATUS Status;
+
+  //
+  //  Use for/break instead of goto
+  //
+  pRsdt = NULL;
+  for ( ; ; ) {
+    //
+    //  Locate the RSDT
+    //
+    Status = EfiGetSystemConfigurationTable ( &gEfiAcpiTableGuid, (VOID **)&pRsdp30 );
+    if ( !EFI_ERROR ( Status )) {
+      pRsdt = (ACPI_RSDT *)pRsdp30->RsdtAddress;
+    }
+    else {
+      Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **)&pRsdp10b );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      pRsdt = (ACPI_RSDT *)pRsdp10b->RsdtAddress;
+    }
+    break;
+  }
+
+  //
+  //  The entry was not found
+  //
+  return pRsdt;
+}
+
+
+/**
+  Locate the specified table
+
+  @param [in] Signature     Table signature
+
+  @returns Table address or NULL if not found
+
+**/
+CONST VOID *
+LocateTable (
+  IN UINT32 Signature
+  )
+{
+  CONST UINT32 * pEnd;
+  CONST UINT32 * pEntry;
+  CONST EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp10b;
+  CONST EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp30;
+  CONST ACPI_RSDT * pRsdt;
+  CONST UINT32 * pSignature;
+  EFI_STATUS Status;
+
+  //
+  //  Use for/break instead of goto
+  //
+  for ( ; ; ) {
+    //
+    //  Locate the RSDT
+    //
+    Status = EfiGetSystemConfigurationTable ( &gEfiAcpiTableGuid, (VOID **)&pRsdp30 );
+    if ( !EFI_ERROR ( Status )) {
+      pRsdt = (ACPI_RSDT *)pRsdp30->RsdtAddress;
+    }
+    else {
+      Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **)&pRsdp10b );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      pRsdt = (ACPI_RSDT *)pRsdp10b->RsdtAddress;
+    }
+
+    //
+    //  Walk the list of entries
+    //
+    pEntry = &pRsdt->Entry [ 0 ];
+    pEnd = &pEntry [(( pRsdt->Length - sizeof ( *pRsdt )) >> 2 ) + 1 ];
+    while ( pEnd > pEntry ) {
+      //
+      //  The entry is actually a 32-bit physical table address
+      //  The first entry in the table is the 32-bit table signature
+      //
+      pSignature = (UINT32 *)*pEntry;
+      if ( *pSignature == Signature ) {
+        return (CONST VOID *) *pEntry;
+      }
+
+      //
+      //  Set the next entry
+      //
+      pEntry++;
+    }
+    break;
+  }
+
+  //
+  //  The entry was not found
+  //
+  return NULL;
+}
+
+
+/**
+  Display a row containing a hex value
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [in] pName         Address of a zero terminated name string
+  @param [in] Length        Length in bytes
+  @param [in] pChar         Address of the first character
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+RowAnsiArray (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  IN CONST CHAR8 * pName,
+  IN UINTN Length,
+  IN CONST CHAR8 * pChar
+  )
+{
+  CONST CHAR8 * pData;
+  CONST CHAR8 * pEnd;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Use for/break instead of goto
+  //
+  for ( ; ; ) {
+    //
+    //  Start the row
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<tr><td>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  pName );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</td><td><code>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the characters
+    //
+    pData = pChar;
+    pEnd = &pChar [ Length ];
+    while ( pEnd > pData ) {
+      Status = HttpSendCharacter ( SocketFD,
+                                   pPort,
+                                   *pData++,
+                                   " " );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+    }
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the byte values
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<br/>0x" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    pData = pChar;
+    while ( pEnd > pData ) {
+      Status = HttpSendHexBits ( SocketFD,
+                                 pPort,
+                                 8,
+                                 *pData++ );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      if ( pEnd > pData ) {
+        Status = HttpSendAnsiString ( SocketFD,
+                                      pPort,
+                                      " 0x" );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+      }
+    }
+
+    //
+    //  Terminate the row
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</code></td></tr>\r\n" );
+    break;
+  }
+
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Format a row with a list of bytes
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [in] pName         Zero terminated name string
+  @param [in] ByteCount     The number of bytes to display
+  @param [in] pData         Address of the byte array
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+RowBytes (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  IN CHAR8 * pName,
+  IN UINTN ByteCount,
+  IN CONST UINT8 * pData
+  )
+{
+  CONST UINT8 * pEnd;
+  EFI_STATUS Status;
+
+  //
+  //  Use for/break instead of goto
+  //
+  for ( ; ; ) {
+    //
+    //  Start the row
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<tr><td>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the field name
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  pName );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the field value
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</td><td><code>0x" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    pEnd = &pData [ ByteCount ];
+    while ( pEnd > pData ) {
+      Status = HttpSendHexBits ( SocketFD,
+                                 pPort,
+                                 8,
+                                 *pData++ );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      if ( pEnd > pData ) {
+        Status = HttpSendAnsiString ( SocketFD,
+                                      pPort,
+                                      " 0x" );
+        if ( EFI_ERROR ( Status )) {
+          break;
+        }
+      }
+    }
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Terminate the row
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</code></td></tr>\r\n" );
+    break;
+  }
+
+  //
+  //  Return the operation status
+  //
+  return Status;
+}
+
+
+/**
+  Format a row with a list of bytes
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [in] pName         Zero terminated name string
+  @param [in] ByteCount     The number of bytes to display
+  @param [in] pData         Address of the byte array
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+RowDump (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  IN CHAR8 * pName,
+  IN UINTN ByteCount,
+  IN CONST UINT8 * pData
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  //  Use for/break instead of goto
+  //
+  for ( ; ; ) {
+    //
+    //  Start the row
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<tr><td>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the field name
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  pName );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Start the field value
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</td><td>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Dump the buffer
+    //
+    Status = HttpSendDump ( SocketFD,
+                            pPort,
+                            ByteCount,
+                            pData );
+
+    //
+    //  Terminate the field value and row
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</td></tr>\r\n" );
+    break;
+  }
+
+  //
+  //  Return the operation status
+  //
+  return Status;
+}
+
+
+/**
+  Format a row with a general address
+
+  @param [in] SocketFD      The socket's file descriptor to add to the list.
+  @param [in] pPort         The WSDT_PORT structure address
+  @param [in] pName         Zero terminated name string
+  @param [in] pAddr         Address of the general address buffer
+  @param [in] pWebPage      Zero terminated web page address
+
+  @retval EFI_SUCCESS       The request was successfully processed
+
+**/
+EFI_STATUS
+RowGenericAddress (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  IN CHAR8 * pName,
+  IN CONST UINT32 * pAddr,
+  IN CONST CHAR16 * pWebPage
+  )
+{
+  CONST GENERIC_ADDRESS * pGenericAddress;
+  EFI_STATUS Status;
+
+  //
+  //  Use for/break instead of goto
+  //
+  for ( ; ; ) {
+    //
+    //  Start the row
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<tr><td>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the field name
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  pName );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the field value
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</td><td><code>" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Determine the type of address
+    //
+    pGenericAddress = (CONST GENERIC_ADDRESS *)pAddr;
+    if ( 0 == pGenericAddress->AddressSpaceId ) {
+      Status = HttpSendAnsiString ( SocketFD, pPort, "System Memory" );
+    }
+    else if ( 1 == pGenericAddress->AddressSpaceId ) {
+      Status = HttpSendAnsiString ( SocketFD, pPort, "I/O Space" );
+    }
+    else if ( 2 == pGenericAddress->AddressSpaceId ) {
+      Status = HttpSendAnsiString ( SocketFD, pPort, "PCI Configuration Space" );
+    }
+    else if ( 3 == pGenericAddress->AddressSpaceId ) {
+      Status = HttpSendAnsiString ( SocketFD, pPort, "Embedded Controller" );
+    }
+    else if ( 4 == pGenericAddress->AddressSpaceId ) {
+      Status = HttpSendAnsiString ( SocketFD, pPort, "SMBus" );
+    }
+    else if ( 0x7f == pGenericAddress->AddressSpaceId ) {
+      Status = HttpSendAnsiString ( SocketFD, pPort, "Functional Fixed Hardware" );
+    }
+    else if (( 0xc0 <= pGenericAddress->AddressSpaceId )
+      && ( 0xff >= pGenericAddress->AddressSpaceId )) {
+      Status = HttpSendAnsiString ( SocketFD, pPort, "OEM Defined" );
+    }
+    else {
+      Status = HttpSendAnsiString ( SocketFD, pPort, "Reserved" );
+    }
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<br/>Register Bit Width: " );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendValue ( SocketFD,
+                             pPort,
+                             pGenericAddress->RegisterBitWidth );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<br/>Register Bit Offset: " );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendHexValue ( SocketFD,
+                                pPort,
+                                pGenericAddress->RegisterBitOffset );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<br/>Access Size: " );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendValue ( SocketFD,
+                             pPort,
+                             pGenericAddress->AccessSize );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "<br/>Address: " );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Add the web-page link if necessary
+    //
+    if ( NULL != pWebPage ) {
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "<a target=\"_blank\" href=\"" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendUnicodeString ( SocketFD,
+                                       pPort,
+                                       pWebPage );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "\">" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+    }
+
+    //
+    //  Display the address
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "0x" );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = HttpSendHexBits ( SocketFD,
+                               pPort,
+                               64,
+                               pGenericAddress->Address );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Finish the web-page link if necessary
+    //
+    if ( NULL != pWebPage ) {
+      Status = HttpSendAnsiString ( SocketFD,
+                                    pPort,
+                                    "</a>" );
+      if ( EFI_ERROR ( Status )) {
+        break;
+      }
+    }
+
+    //
+    //  Terminate the row
+    //
+    Status = HttpSendAnsiString ( SocketFD,
+                                  pPort,
+                                  "</code></td></tr>\r\n" );
+    break;
+  }
+
+  //
+  //  Return the operation status
+  //
+  return Status;
+}
+
+
+/**
+  Translate a table address into a web page
+
+  @param [in] pSignature      Address of the table signature
+  @param [out] ppTableName    Address to receive the table name address
+
+  @returns Zero terminated web page address or NULL if not found
+
+**/
+CONST CHAR16 *
+SignatureLookup (
+  IN UINT32 * pSignature,
+  OUT CONST CHAR8 ** ppTableName
+  )
+{
+  CONST TABLE_SIGNATURE * pTableId;
+  CONST TABLE_SIGNATURE * pEnd;
+  UINT32 Signature;
+
+  //
+  //  Walk the list of tables
+  //
+  Signature = *pSignature;
+  pTableId = &mTableId [ 0 ];
+  pEnd = &pTableId [ sizeof ( mTableId ) / sizeof ( mTableId [ 0 ])];
+  while ( pEnd > pTableId ) {
+    //
+    //  Attempt to locate the table signature
+    //
+    if ( pTableId->Signature == Signature ) {
+      //
+      //  The signature was found
+      //  Return the web page
+      //
+      *ppTableName = pTableId->pTableName;
+      return pTableId->pWebPage;
+    }
+
+    //
+    //  Set the next table
+    //
+    pTableId += 1;
+  }
+
+  //
+  //  The table was not found
+  //
+  *ppTableName = (CONST CHAR8 *)pSignature;
+  return NULL;
+}
+
+
+/**
+  Respond with the ACPI DSDT table
+
+  @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
+AcpiDsdtPage (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  CONST ACPI_DSDT * pDsdt;
+  CONST ACPI_FADT * pFadt;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+  
+  //
+  //  Send the DADT page
+  //
+  for ( ; ; ) {
+    //
+    //  Locate the DADT
+    //
+    pFadt = (ACPI_FADT *)LocateTable ( FADT_SIGNATURE );
+    if ( NULL == pFadt ) {
+      Status = EFI_NOT_FOUND;
+      break;
+    }
+    pDsdt = (VOID *)pFadt->XDsdt;
+
+    //
+    //  Send the page and table header
+    //
+    Status = TableHeader ( SocketFD, pPort, L"DSDT - Differentiated System Description Table", pDsdt );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the DSDT header
+    //
+    Status = RowAnsiArray ( SocketFD,
+                            pPort,
+                            "Signature",
+                            sizeof ( pDsdt->Signature ),
+                            (CHAR8 *)&pDsdt->Signature );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "Length",
+                               pDsdt->Length );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "Revision",
+                               pDsdt->Revision );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Checksum",
+                           pDsdt->Checksum,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowAnsiArray ( SocketFD,
+                            pPort,
+                            "OEMID",
+                            sizeof ( pDsdt->OemId ),
+                            &pDsdt->OemId [ 0 ]);
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowAnsiArray ( SocketFD,
+                            pPort,
+                            "OEM Table ID",
+                            sizeof ( pDsdt->OemTableId ),
+                            &pDsdt->OemTableId [ 0 ]);
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowRevision ( SocketFD,
+                           pPort,
+                           "OEM Revision",
+                           pDsdt->OemRevision );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowAnsiArray ( SocketFD,
+                            pPort,
+                            "Creator ID",
+                            sizeof ( pDsdt->CreatorId ),
+                            (CHAR8 *)&pDsdt->CreatorId );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowRevision ( SocketFD,
+                           pPort,
+                           "Creator Revision",
+                           pDsdt->CreatorRevision );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the data from the DSDT
+    //
+    Status = RowDump ( SocketFD,
+                       pPort,
+                       "Definition Block",
+                       pDsdt->Length - sizeof ( *pDsdt ) + 1,
+                       &pDsdt->DefinitionBlock[0]);
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Build the table trailer
+    //
+    Status = TableTrailer ( SocketFD,
+                            pPort,
+                            pbDone );
+    break;
+  }
+    
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Respond with the ACPI FADT table
+
+  @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
+AcpiFadtPage (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  CONST ACPI_FADT * pFadt;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+  
+  //
+  //  Send the FADT page
+  //
+  for ( ; ; ) {
+    //
+    //  Locate the FADT
+    //
+    pFadt = (ACPI_FADT *)LocateTable ( FADT_SIGNATURE );
+    if ( NULL == pFadt ) {
+      Status = EFI_NOT_FOUND;
+      break;
+    }
+
+    //
+    //  Send the page and table header
+    //
+    Status = TableHeader ( SocketFD, pPort, L"FADT - Fixed ACPI Description Table", pFadt );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the FSDT header
+    //
+    Status = RowAnsiArray ( SocketFD,
+                            pPort,
+                            "Signature",
+                            sizeof ( pFadt->Signature ),
+                            (CHAR8 *)&pFadt->Signature );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "Length",
+                               pFadt->Length );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "Revision",
+                               pFadt->Revision );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Checksum",
+                           pFadt->Checksum,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowAnsiArray ( SocketFD,
+                            pPort,
+                            "OEMID",
+                            sizeof ( pFadt->OemId ),
+                            &pFadt->OemId [ 0 ]);
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowAnsiArray ( SocketFD,
+                            pPort,
+                            "OEM Table ID",
+                            sizeof ( pFadt->OemTableId ),
+                            &pFadt->OemTableId [ 0 ]);
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowRevision ( SocketFD,
+                           pPort,
+                           "OEM Revision",
+                           pFadt->OemRevision );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowAnsiArray ( SocketFD,
+                            pPort,
+                            "Creator ID",
+                            sizeof ( pFadt->CreatorId ),
+                            (CHAR8 *)&pFadt->CreatorId );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowRevision ( SocketFD,
+                           pPort,
+                           "Creator Revision",
+                           pFadt->CreatorRevision );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the data from the FADT
+    //
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "FIRMWARE_CTRL",
+                          (CONST VOID *)pFadt->FirmwareCtrl,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "DSDT",
+                          (CONST VOID *)pFadt->DSDT,
+                          ( pFadt->DSDT == pFadt->XDsdt ) ? PAGE_ACPI_DSDT : NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Reserved",
+                           pFadt->Reserved,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Preferred_PM_Profile",
+                           pFadt->PreferredPmProfile,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "SCI_INT",
+                           pFadt->SciInt,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "SMI_CMD",
+                           pFadt->SmiCmd,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "ACPI_ENABLE",
+                           pFadt->AcpiEnable,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "ACPI_DISABLE",
+                           pFadt->AcpiDisable,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "S4BIOS_REQ",
+                           pFadt->S4BiosReq,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "PSTATE_CNT",
+                           pFadt->PStateCnt,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "PM1a_EVT_BLK",
+                           pFadt->Pm1aEvtBlk,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "PM1b_EVT_BLK",
+                           pFadt->Pm1bEvtBlk,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "PM1a_CNT_BLK",
+                           pFadt->Pm1aCntBlk,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "PM1b_CNT_BLK",
+                           pFadt->Pm1bCntBlk,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "PM2_CNT_BLK",
+                           pFadt->Pm2CntBlk,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "PM_TMR_BLK",
+                           pFadt->PmTmrBlk,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "GPE0_BLK",
+                           pFadt->Gpe0Blk,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "GPE1_BLK",
+                           pFadt->Gpe1Blk,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "PM1_EVT_LEN",
+                               pFadt->Pm1EvtLen );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "PM1_CNT_LEN",
+                               pFadt->Pm1CntLen );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "PM2_CNT_LEN",
+                               pFadt->PM2CntLen );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "PM_TMR_LEN",
+                               pFadt->PmTmrLen );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "GPE0_BLK_LEN",
+                               pFadt->Gpe0BlkLen );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "GPE1_BLK_LEN",
+                               pFadt->Gpe1BlkLen );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "GPE1_BASE",
+                           pFadt->Gpe1Base,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "CST_CNT",
+                               pFadt->CstCnt );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "P_LVL2_LAT",
+                           pFadt->PLvl2Lat,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "P_LVL3_LAT",
+                           pFadt->PLvl3Lat,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "FLUSH_SIZE",
+                               pFadt->FlushSize );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "FLUSH_Stride",
+                               pFadt->FlushStride );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "DUTY_OFFSET",
+                           pFadt->DutyOffset,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "DUTY_WIDTH",
+                           pFadt->DutyWidth,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "DAY_ALRM",
+                           pFadt->DayAlrm,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "MON_ALRM",
+                           pFadt->MonAlrm,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "CENTURY",
+                           pFadt->Century,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "IAPC_BOOT_ARCH",
+                           pFadt->IapcBootArch,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Reserved",
+                           pFadt->Reserved2,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Flags",
+                           pFadt->Flags,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowGenericAddress ( SocketFD,
+                                 pPort,
+                                 "RESET_REG",
+                                 &pFadt->ResetReg[0],
+                                 NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "RESET_VALUE",
+                           pFadt->ResetValue,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Reserved",
+                           pFadt->Reserved3[0],
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Reserved",
+                           pFadt->Reserved3[1],
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Reserved",
+                           pFadt->Reserved3[2],
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "X_FIRMWARE_CTRL",
+                           pFadt->XFirmwareCtrl,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "X_DSDT",
+                           pFadt->XDsdt,
+                           PAGE_ACPI_DSDT );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowGenericAddress ( SocketFD,
+                                 pPort,
+                                 "X_PM1a_EVT_BLK",
+                                 &pFadt->XPm1aEvtBlk[0],
+                                 NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowGenericAddress ( SocketFD,
+                                 pPort,
+                                 "X_PM1b_EVT_BLK",
+                                 &pFadt->XPm1bEvtBlk[0],
+                                 NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowGenericAddress ( SocketFD,
+                                 pPort,
+                                 "X_PM1a_CNT_BLK",
+                                 &pFadt->XPm1aCntBlk[0],
+                                 NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowGenericAddress ( SocketFD,
+                                 pPort,
+                                 "X_PM1b_CNT_BLK",
+                                 &pFadt->XPm1bCntBlk[0],
+                                 NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowGenericAddress ( SocketFD,
+                                 pPort,
+                                 "X_PM2_CNT_BLK",
+                                 &pFadt->XPm2CntBlk[0],
+                                 NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowGenericAddress ( SocketFD,
+                                 pPort,
+                                 "X_PM_TMR_BLK",
+                                 &pFadt->XPmTmrBlk[0],
+                                 NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowGenericAddress ( SocketFD,
+                                 pPort,
+                                 "X_GPE0_BLK",
+                                 &pFadt->XGpe0Blk[0],
+                                 NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowGenericAddress ( SocketFD,
+                                 pPort,
+                                 "X_GPE1_BLK",
+                                 &pFadt->XGpe1Blk[0],
+                                 NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Build the table trailer
+    //
+    Status = TableTrailer ( SocketFD,
+                            pPort,
+                            pbDone );
+    break;
+  }
+    
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Respond with the ACPI RSDP 1.0b table
+
+  @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
+AcpiRsdp10Page (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  CONST EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp10b;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+  
+  //
+  //  Send the RSDP page
+  //
+  for ( ; ; ) {
+    //
+    //  Locate the RSDP
+    //
+    Status = EfiGetSystemConfigurationTable ( &gEfiAcpi10TableGuid, (VOID **) &pRsdp10b );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Send the page and table header
+    //
+    Status = TableHeader ( SocketFD, pPort, L"RSDP - ACPI 1.0b Root System Description Pointer", pRsdp10b );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the RSDP
+    //
+    Status = RowAnsiArray ( SocketFD,
+                            pPort,
+                            "Signature",
+                            sizeof ( pRsdp10b->Signature ),
+                            (CHAR8 *)&pRsdp10b->Signature );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Checksum",
+                           pRsdp10b->Checksum,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowAnsiArray ( SocketFD,
+                            pPort,
+                            "OemId",
+                            sizeof ( pRsdp10b->OemId ),
+                            &pRsdp10b->OemId [ 0 ]);
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Reserved",
+                           pRsdp10b->Reserved,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "RsdtAddress",
+                          (VOID *)pRsdp10b->RsdtAddress,
+                          PAGE_ACPI_RSDT );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Build the table trailer
+    //
+    Status = TableTrailer ( SocketFD,
+                            pPort,
+                            pbDone );
+    break;
+  }
+    
+  //
+  //  Return the operation status
+  //
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
+
+
+/**
+  Respond with the ACPI RSDP 3.0 table
+
+  @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
+AcpiRsdp30Page (
+  IN int SocketFD,
+  IN WSDT_PORT * pPort,
+  OUT BOOLEAN * pbDone
+  )
+{
+  CONST EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER * pRsdp30;
+  EFI_STATUS Status;
+
+  DBG_ENTER ( );
+  
+  //
+  //  Send the RSDP page
+  //
+  for ( ; ; ) {
+    //
+    //  Locate the RSDP
+    //
+    Status = EfiGetSystemConfigurationTable ( &gEfiAcpiTableGuid, (VOID **) &pRsdp30 );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Send the page and table header
+    //
+    Status = TableHeader ( SocketFD, pPort, L"RSDP - ACPI 3.0 Root System Description Pointer", pRsdp30 );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Display the RSDP
+    //
+    Status = RowAnsiArray ( SocketFD,
+                            pPort,
+                            "Signature",
+                            sizeof ( pRsdp30->Signature ),
+                            (CHAR8 *)&pRsdp30->Signature );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Checksum",
+                           pRsdp30->Checksum,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowAnsiArray ( SocketFD,
+                            pPort,
+                            "OemId",
+                            sizeof ( pRsdp30->OemId ),
+                            &pRsdp30->OemId [ 0 ]);
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "Revision",
+                           pRsdp30->Revision,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "RsdtAddress",
+                          (VOID *)pRsdp30->RsdtAddress,
+                          PAGE_ACPI_RSDT );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowDecimalValue ( SocketFD,
+                               pPort,
+                               "Length",
+                               pRsdp30->Length );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowPointer ( SocketFD,
+                          pPort,
+                          "XsdtAddress",
+                          (VOID *)pRsdp30->XsdtAddress,
+                          NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowHexValue ( SocketFD,
+                           pPort,
+                           "ExtendedChecksum",
+                           pRsdp30->ExtendedChecksum,
+                           NULL );
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+    Status = RowBytes ( SocketFD,
+                        pPort,
+                        "Reserved",
+                        sizeof ( pRsdp30->Reserved ),
+                        &pRsdp30->Reserved [ 0 ]);
+    if ( EFI_ERROR ( Status )) {
+      break;
+    }
+
+    //
+    //  Build the table trailer
+    //
+    Status = TableTrailer ( SocketFD,
+                            pPort,