]> git.proxmox.com Git - mirror_edk2.git/blobdiff - AppPkg/Applications/Sockets/DataSource/DataSource.c
- For writing sin_port, htons() must be used.
[mirror_edk2.git] / AppPkg / Applications / Sockets / DataSource / DataSource.c
index d8f7f05d5c6fce0c80fa506b4916d8939d4ba8e6..0dcd882edf7e70ef9848934a371e0861cfba5617 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Data source for network testing.\r
 \r
-  Copyright (c) 2011, Intel Corporation\r
+  Copyright (c) 2011-2012, 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
 #include <sys/poll.h>\r
 #include <sys/socket.h>\r
 \r
+#include <stdio.h>\r
+#include <string.h>\r
 \r
-#define RANGE_SWITCH                2048  ///<  Switch display ranges\r
-#define DATA_RATE_UPDATE_SHIFT      2     ///<  2n seconds between updates\r
+\r
+#define DATA_SAMPLE_SHIFT           5       ///<  Shift for number of samples\r
+#define RANGE_SWITCH        ( 1024 * 1024 ) ///<  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
+#define DATA_SAMPLES        ( 1 << DATA_SAMPLE_SHIFT )      ///<  Number of samples\r
 \r
 #define TPL_DATASOURCE      TPL_CALLBACK  ///<  Synchronization TPL\r
 \r
@@ -74,17 +79,17 @@ EFI_EVENT pTimer;
 //\r
 //  Remote IP Address Data\r
 //\r
-struct sockaddr_in RemoteHostAddress;\r
+struct sockaddr_in6 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
+UINT32 In;\r
+UINT32 Samples;\r
+UINT64 BytesSent[ DATA_SAMPLES ];\r
+UINT8 Buffer[ DATA_BUFFER_SIZE ];\r
 \r
 \r
 //\r
@@ -131,7 +136,7 @@ ControlCCheck (
   @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
+  @return   Returns the address of the separator\r
 \r
 **/\r
 CHAR8 *\r
@@ -146,8 +151,7 @@ GetDigit (
   //  Walk the digits\r
   //\r
   Value = 0;\r
-  while (( '0' <= *pDigit ) && ( '9' >= *pDigit ))\r
-  {\r
+  while (( '0' <= *pDigit ) && ( '9' >= *pDigit )) {\r
     //\r
     //  Make room for the new least significant digit\r
     //\r
@@ -186,48 +190,124 @@ EFI_STATUS
 IpAddress (\r
   )\r
 {\r
-  CHAR8 * pSeparator;\r
-  INT32 RemoteAddress;\r
+  struct sockaddr_in * pRemoteAddress4;\r
+  struct sockaddr_in6 * pRemoteAddress6;\r
+  UINT32 RemoteAddress;\r
   EFI_STATUS Status;\r
   UINT32 Value1;\r
   UINT32 Value2;\r
   UINT32 Value3;\r
   UINT32 Value4;\r
+  UINT32 Value5;\r
+  UINT32 Value6;\r
+  UINT32 Value7;\r
+  UINT32 Value8;\r
 \r
   //\r
   //  Assume failure\r
   //\r
   Status = EFI_INVALID_PARAMETER;\r
 \r
+  //\r
+  //  Get the port number\r
+  //\r
+  ZeroMem ( &RemoteHostAddress, sizeof ( RemoteHostAddress ));\r
+  RemoteHostAddress.sin6_port = htons ( PcdGet16 ( DataSource_Port ));\r
+  pRemoteAddress4 = (struct sockaddr_in *)&RemoteHostAddress;\r
+  pRemoteAddress6 = &RemoteHostAddress;\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
+  if (( 4 == sscanf ( pRemoteHost,\r
+                      "%d.%d.%d.%d",\r
+                      &Value1,\r
+                      &Value2,\r
+                      &Value3,\r
+                      &Value4 ))\r
+      && ( 255 >= Value1 )\r
+      && ( 255 >= Value2 )\r
+      && ( 255 >= Value3 )\r
+      && ( 255 >= Value4 )) {\r
+    //\r
+    //  Build the IPv4 address\r
+    //\r
+    pRemoteAddress4->sin_len = sizeof ( *pRemoteAddress4 );\r
+    pRemoteAddress4->sin_family = AF_INET;\r
+    RemoteAddress = Value1\r
+                  | ( Value2 << 8 )\r
+                  | ( Value3 << 16 )\r
+                  | ( Value4 << 24 );\r
+    pRemoteAddress4->sin_addr.s_addr = RemoteAddress;\r
+    Status = EFI_SUCCESS;\r
+\r
+    //\r
+    //  Display the IP address\r
+    //\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
-  if ( EFI_ERROR ( Status )) {\r
-    Print ( L"Invalid digit detected: %d\r\n", *pSeparator );\r
+  else if (( 8 == sscanf ( pRemoteHost,\r
+                           "%x:%x:%x:%x:%x:%x:%x:%x",\r
+                           &Value1,\r
+                           &Value2,\r
+                           &Value3,\r
+                           &Value4,\r
+                           &Value5,\r
+                           &Value6,\r
+                           &Value7,\r
+                           &Value8 ))\r
+            && ( 0xffff >= Value1 )\r
+            && ( 0xffff >= Value2 )\r
+            && ( 0xffff >= Value3 )\r
+            && ( 0xffff >= Value4 )\r
+            && ( 0xffff >= Value5 )\r
+            && ( 0xffff >= Value6 )\r
+            && ( 0xffff >= Value7 )\r
+            && ( 0xffff >= Value8 )) {\r
+    //\r
+    //  Build the IPv6 address\r
+    //\r
+    pRemoteAddress6->sin6_len = sizeof ( *pRemoteAddress6 );\r
+    pRemoteAddress6->sin6_family = AF_INET6;\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ] = (UINT8)( Value1 >> 8 );\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ] = (UINT8)Value1;\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ] = (UINT8)( Value2 >> 8 );\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ] = (UINT8)Value2;\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ] = (UINT8)( Value3 >> 8 );\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ] = (UINT8)Value3;\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ] = (UINT8)( Value4 >> 8 );\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ] = (UINT8)Value4;\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ] = (UINT8)( Value5 >> 8 );\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ] = (UINT8)Value5;\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ] = (UINT8)( Value6 >> 8 );\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ] = (UINT8)Value6;\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ] = (UINT8)( Value7 >> 8 );\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ] = (UINT8)Value7;\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ] = (UINT8)( Value8 >> 8 );\r
+    pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ] = (UINT8)Value8;\r
+    Status = EFI_SUCCESS;\r
+\r
+    //\r
+    //  Display the IP address\r
+    //\r
+    DEBUG (( DEBUG_INFO,\r
+              "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]: Remote host IP address\r\n",\r
+              Value1,\r
+              Value2,\r
+              Value3,\r
+              Value4,\r
+              Value5,\r
+              Value6,\r
+              Value7,\r
+              Value8 ));\r
+  }\r
+  else {\r
+    Print ( L"ERROR - Invalid IP address!\r\n" );\r
   }\r
 \r
   //\r
@@ -291,19 +371,43 @@ SocketConnect (
   )\r
 {\r
   int ConnectStatus;\r
-  UINT32 RemoteAddress;\r
+  struct sockaddr_in * pRemoteAddress4;\r
+  struct sockaddr_in6 * pRemoteAddress6;\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
+  pRemoteAddress4 = (struct sockaddr_in *)&RemoteHostAddress;\r
+  pRemoteAddress6 = &RemoteHostAddress;\r
+  if ( AF_INET == pRemoteAddress6->sin6_family ) {\r
+    Print ( L"Connecting to remote system %d.%d.%d.%d:%d\r\n",\r
+            pRemoteAddress4->sin_addr.s_addr & 0xff,\r
+            ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,\r
+            ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,\r
+            ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,\r
+            ntohs ( pRemoteAddress4->sin_port ));\r
+  }\r
+  else {\r
+    Print ( L"Connecting to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],\r
+            pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],\r
+            ntohs ( pRemoteAddress6->sin6_port ));\r
+  }\r
 \r
   //\r
   //  Connect to the remote system\r
@@ -313,7 +417,7 @@ SocketConnect (
     //\r
     //  Check for user stop request\r
     //\r
-    while ( ! bTick ) {\r
+    while ( !bTick ) {\r
       Status = ControlCCheck ( );\r
       if ( EFI_ERROR ( Status )) {\r
         break;\r
@@ -328,15 +432,38 @@ SocketConnect (
     //  Connect to the remote system\r
     //\r
     ConnectStatus = connect ( Socket,\r
-                              (struct sockaddr *) &RemoteHostAddress,\r
-                              RemoteHostAddress.sin_len );\r
+                              (struct sockaddr *)pRemoteAddress6,\r
+                              pRemoteAddress6->sin6_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
+      if ( AF_INET == pRemoteAddress6->sin6_family ) {\r
+        Print ( L"Connected to remote system %d.%d.%d.%d:%d\r\n",\r
+                pRemoteAddress4->sin_addr.s_addr & 0xff,\r
+                ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,\r
+                ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,\r
+                ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,\r
+                ntohs ( pRemoteAddress4->sin_port ));\r
+      }\r
+      else {\r
+        Print ( L"Connected to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],\r
+                pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],\r
+                ntohs ( pRemoteAddress6->sin6_port ));\r
+      }\r
+Print ( L"ConnectStatus: %d, Status: %r\r\n", ConnectStatus, Status );\r
     }\r
     else {\r
       //\r
@@ -352,6 +479,7 @@ SocketConnect (
   //\r
   //  Return the operation status\r
   //\r
+Print ( L"SocketConnect returning Status: %r\r\n", Status );\r
   return Status;\r
 }\r
 \r
@@ -359,11 +487,14 @@ SocketConnect (
 /**\r
   Create the socket\r
 \r
+  @param [in] Family    Network family, AF_INET or AF_INET6\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
+  sa_family_t Family\r
   )\r
 {\r
   EFI_STATUS Status;\r
@@ -385,7 +516,7 @@ SocketNew (
     //\r
     //  Attempt to create the socket\r
     //\r
-    Socket = socket ( AF_INET,\r
+    Socket = socket ( Family,\r
                       SOCK_STREAM,\r
                       IPPROTO_TCP );\r
     if ( -1 != Socket ) {\r
@@ -420,7 +551,7 @@ SocketSend (
   //\r
   //  Restart the timer\r
   //\r
-  TimerStart ( 1000 << DATA_RATE_UPDATE_SHIFT );\r
+  TimerStart ( 1 * 1000 );\r
 \r
   //\r
   //  Loop until the connection breaks or the user stops\r
@@ -442,6 +573,7 @@ SocketSend (
       DEBUG (( DEBUG_INFO,\r
                 "ERROR: send failed, errno: %d\r\n",\r
                 errno ));\r
+Print ( L"ERROR: send failed, errno: %d\r\n", errno );\r
 \r
       //\r
       //  Try again\r
@@ -494,12 +626,11 @@ SocketOpen (
   //\r
   //  Use do/while and break instead of goto\r
   //\r
-  do\r
-  {\r
+  do {\r
     //\r
     //  Wait for the network layer to initialize\r
     //\r
-    Status = SocketNew ( );\r
+    Status = SocketNew ( RemoteHostAddress.sin6_family );\r
     if ( EFI_ERROR ( Status )) {\r
       break;\r
     }\r
@@ -508,6 +639,7 @@ SocketOpen (
     //  Wait for the remote network application to start\r
     //\r
     Status = SocketConnect ( );\r
+Print ( L"Status: %r\r\n", Status );\r
     if ( EFI_NOT_STARTED == Status ) {\r
       Status = SocketClose ( );\r
       continue;\r
@@ -531,6 +663,7 @@ SocketOpen (
   //\r
   //  Return the operation status\r
   //\r
+Print ( L"Returning Status: %r\r\n", Status );\r
   return Status;\r
 }\r
 \r
@@ -586,13 +719,13 @@ Tcp4Close (
           //\r
           //  Display the port closed message\r
           //\r
-          pIpAddress = (UINT8 *)&RemoteHostAddress.sin_addr.s_addr;\r
+          pIpAddress = (UINT8 *)&((struct sockaddr_in *)&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
+                  ntohs ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));\r
         }\r
       }\r
     }\r
@@ -775,7 +908,7 @@ Tcp4Locate (
     //\r
     if ( HandleCount <= Tcp4Index ) {\r
       Tcp4Index = 0;\r
-    \r
+\r
       //\r
       //  Wait for the next timer tick\r
       //\r
@@ -788,20 +921,20 @@ Tcp4Locate (
     //  Display the connecting message\r
     //\r
     if ( bTcp4Connecting ) {\r
-      pIpAddress = (UINT8 *)&RemoteHostAddress.sin_addr.s_addr;\r
+      pIpAddress = (UINT8 *)&((struct sockaddr_in *)&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
+              ntohs ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));\r
       bTcp4Connecting = FALSE;\r
     }\r
-    \r
+\r
     //\r
     //  Open the network controller's service protocol\r
     //\r
-    Tcp4Controller = pHandles [ Tcp4Index++ ];\r
+    Tcp4Controller = pHandles[ Tcp4Index++ ];\r
     Status = gBS->OpenProtocol (\r
                     Tcp4Controller,\r
                     &gEfiTcp4ServiceBindingProtocolGuid,\r
@@ -887,7 +1020,7 @@ Tcp4Send (
   //\r
   //  Restart the timer\r
   //\r
-  TimerStart ( 1000 << DATA_RATE_UPDATE_SHIFT );\r
+  TimerStart ( 1 * 1000 );\r
 \r
   //\r
   //  Initialize the packet\r
@@ -1097,11 +1230,11 @@ Tcp4Open (
     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.RemoteAddress.Addr[0] = (UINT8)  ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr;\r
+    Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[1] = (UINT8)( ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr >> 8 );\r
+    Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[2] = (UINT8)( ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr >> 16 );\r
+    Tcp4ConfigData.AccessPoint.RemoteAddress.Addr[3] = (UINT8)( ((struct sockaddr_in *)&RemoteHostAddress)->sin_addr.s_addr >> 24 );\r
+    Tcp4ConfigData.AccessPoint.RemotePort = ntohs (((struct sockaddr_in *)&RemoteHostAddress)->sin_port);\r
     Tcp4ConfigData.AccessPoint.UseDefaultAddress = TRUE;\r
     Tcp4ConfigData.AccessPoint.SubnetMask.Addr[0] = 0;\r
     Tcp4ConfigData.AccessPoint.SubnetMask.Addr[1] = 0;\r
@@ -1110,7 +1243,7 @@ Tcp4Open (
     Status = pTcp4Protocol->Configure ( pTcp4Protocol,\r
                                         &Tcp4ConfigData );\r
     if ( EFI_ERROR ( Status )) {\r
-      DEBUG (( DEBUG_ERROR, \r
+      DEBUG (( DEBUG_ERROR,\r
                 "ERROR - Failed to configure TCP port, Status: %r\r\n",\r
                 Status ));\r
       break;\r
@@ -1154,13 +1287,13 @@ Tcp4Open (
     //\r
     //  Display the connection\r
     //\r
-    pIpAddress = (UINT8 *)&RemoteHostAddress.sin_addr.s_addr;\r
+    pIpAddress = (UINT8 *)&((struct sockaddr_in *)&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
+            ntohs ( ((struct sockaddr_in *)&RemoteHostAddress)->sin_port ));\r
   } while ( 0 );\r
 \r
   if ( EFI_ERROR ( Status )) {\r
@@ -1190,15 +1323,16 @@ Tcp4Open (
   @param [in] pContext  Context for this routine\r
 **/\r
 VOID\r
+EFIAPI\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
+  UINT32 Average;\r
+  UINT64 BitsPerSecond;\r
+  UINT32 Index;\r
+  UINT64 TotalBytes;\r
 \r
   //\r
   //  Notify the other code of the timer tick\r
@@ -1208,65 +1342,82 @@ TimerCallback (
   //\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
+  if ( 0 != TotalBytesSent ) {\r
+    BytesSent[ In ] = TotalBytesSent;\r
+    TotalBytesSent = 0;\r
+    In += 1;\r
+    if ( DATA_SAMPLES <= In ) {\r
+      In = 0;\r
+    }\r
 \r
     //\r
     //  Separate the samples\r
     //\r
-    if (( 2 << AVERAGE_SHIFT_COUNT ) == Samples ) {\r
+    if ( DATA_SAMPLES == Samples ) {\r
       Print ( L"---------- Stable average ----------\r\n" );\r
     }\r
     Samples += 1;\r
 \r
+    //\r
+    //  Compute the data rate\r
+    //\r
+    TotalBytes = 0;\r
+    for ( Index = 0; DATA_SAMPLES > Index; Index++ ) {\r
+      TotalBytes += BytesSent[ Index ];\r
+    }\r
+    Average = (UINT32)RShiftU64 ( TotalBytes, DATA_SAMPLE_SHIFT );\r
+    BitsPerSecond = Average * 8;\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
+    if (( RANGE_SWITCH >> 10 ) > Average ) {\r
+      Print ( L"Ave: %d Bytes/Sec, %Ld Bits/sec\r\n",\r
+              Average,\r
+              BitsPerSecond );\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
+      BitsPerSecond /= 1000;\r
+      if ( RANGE_SWITCH > Average ) {\r
+        Print ( L"Ave: %d.%03d KiBytes/Sec, %Ld KBits/sec\r\n",\r
+                Average >> 10,\r
+                (( Average & 0x3ff ) * 1000 ) >> 10,\r
+                BitsPerSecond );\r
       }\r
       else {\r
+        BitsPerSecond /= 1000;\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
+        if ( RANGE_SWITCH > Average ) {\r
+          Print ( L"Ave: %d.%03d MiBytes/Sec, %Ld MBits/sec\r\n",\r
+                  Average >> 10,\r
+                  (( Average & 0x3ff ) * 1000 ) >> 10,\r
+                  BitsPerSecond );\r
         }\r
         else {\r
+          BitsPerSecond /= 1000;\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
+          if ( RANGE_SWITCH > Average ) {\r
+            Print ( L"Ave: %d.%03d GiBytes/Sec, %Ld GBits/sec\r\n",\r
+                    Average >> 10,\r
+                    (( Average & 0x3ff ) * 1000 ) >> 10,\r
+                    BitsPerSecond );\r
           }\r
           else {\r
+            BitsPerSecond /= 1000;\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
+            if ( RANGE_SWITCH > Average ) {\r
+              Print ( L"Ave: %d.%03d TiBytes/Sec, %Ld TBits/sec\r\n",\r
+                      Average >> 10,\r
+                      (( Average & 0x3ff ) * 1000 ) >> 10,\r
+                      BitsPerSecond );\r
             }\r
             else {\r
+              BitsPerSecond /= 1000;\r
               Average >>= 10;\r
-              Print ( L"%d Bytes/sec, Ave: %d PiBytes/Sec\r\n",\r
-                      Delta,\r
-                      (UINT32) Average );\r
+              Print ( L"Ave: %d.%03d PiBytes/Sec, %Ld PBits/sec\r\n",\r
+                      Average >> 10,\r
+                      (( Average & 0x3ff ) * 1000 ) >> 10,\r
+                      BitsPerSecond );\r
             }\r
           }\r
         }\r
@@ -1499,12 +1650,15 @@ main (
   //\r
   //  Validate the command line\r
   //\r
-  if ( 2 != Argc ) {\r
-    Print ( L"%s  <remote IP address>\r\n", Argv[0] );\r
+  if ( 2 > Argc ) {\r
+    Print ( L"%s  <remote IP address> [Use TCP]\r\n", Argv[0] );\r
     return -1;\r
   }\r
 \r
-bTcp4 = TRUE;\r
+  //\r
+  //  Determine if TCP should be used\r
+  //\r
+  bTcp4 = (BOOLEAN)( 2 < Argc );\r
 \r
   //\r
   //  Determine the support routines\r
@@ -1522,32 +1676,18 @@ bTcp4 = TRUE;
   //\r
   //  Use for/break instead of goto\r
   //\r
-  for ( ; ; )\r
-  {\r
+  for ( ; ; ) {\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
+    memset ( &BytesSent, 0, sizeof ( BytesSent ));\r
 \r
     //\r
     //  Get the IP address\r
     //\r
-    pRemoteHost = Argv [1];\r
+    pRemoteHost = Argv[1];\r
     Status = IpAddress ( );\r
     if ( EFI_ERROR ( Status )) {\r
       break;\r