]> 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
 /** @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
   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 <sys/poll.h>\r
 #include <sys/socket.h>\r
 \r
+#include <stdio.h>\r
+#include <string.h>\r
 \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 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
 \r
 #define TPL_DATASOURCE      TPL_CALLBACK  ///<  Synchronization TPL\r
 \r
@@ -74,17 +79,17 @@ EFI_EVENT pTimer;
 //\r
 //  Remote IP Address Data\r
 //\r
 //\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
 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
 \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
   @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
 \r
 **/\r
 CHAR8 *\r
@@ -146,8 +151,7 @@ GetDigit (
   //  Walk the digits\r
   //\r
   Value = 0;\r
   //  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
     //\r
     //  Make room for the new least significant digit\r
     //\r
@@ -186,48 +190,124 @@ EFI_STATUS
 IpAddress (\r
   )\r
 {\r
 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
   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
   //\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
   //\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
   }\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
   }\r
 \r
   //\r
@@ -291,19 +371,43 @@ SocketConnect (
   )\r
 {\r
   int ConnectStatus;\r
   )\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
   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
 \r
   //\r
   //  Connect to the remote system\r
@@ -313,7 +417,7 @@ SocketConnect (
     //\r
     //  Check for user stop request\r
     //\r
     //\r
     //  Check for user stop request\r
     //\r
-    while ( ! bTick ) {\r
+    while ( !bTick ) {\r
       Status = ControlCCheck ( );\r
       if ( EFI_ERROR ( Status )) {\r
         break;\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
     //  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
     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
     }\r
     else {\r
       //\r
@@ -352,6 +479,7 @@ SocketConnect (
   //\r
   //  Return the operation status\r
   //\r
   //\r
   //  Return the operation status\r
   //\r
+Print ( L"SocketConnect returning Status: %r\r\n", Status );\r
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
 \r
@@ -359,11 +487,14 @@ SocketConnect (
 /**\r
   Create the socket\r
 \r
 /**\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
   @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
   )\r
 {\r
   EFI_STATUS Status;\r
@@ -385,7 +516,7 @@ SocketNew (
     //\r
     //  Attempt to create the socket\r
     //\r
     //\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
                       SOCK_STREAM,\r
                       IPPROTO_TCP );\r
     if ( -1 != Socket ) {\r
@@ -420,7 +551,7 @@ SocketSend (
   //\r
   //  Restart the timer\r
   //\r
   //\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
 \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
       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
 \r
       //\r
       //  Try again\r
@@ -494,12 +626,11 @@ SocketOpen (
   //\r
   //  Use do/while and break instead of goto\r
   //\r
   //\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
     //\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
     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
     //  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
     if ( EFI_NOT_STARTED == Status ) {\r
       Status = SocketClose ( );\r
       continue;\r
@@ -531,6 +663,7 @@ SocketOpen (
   //\r
   //  Return the operation status\r
   //\r
   //\r
   //  Return the operation status\r
   //\r
+Print ( L"Returning Status: %r\r\n", Status );\r
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
 \r
@@ -586,13 +719,13 @@ Tcp4Close (
           //\r
           //  Display the port closed message\r
           //\r
           //\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
           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
         }\r
       }\r
     }\r
@@ -775,7 +908,7 @@ Tcp4Locate (
     //\r
     if ( HandleCount <= Tcp4Index ) {\r
       Tcp4Index = 0;\r
     //\r
     if ( HandleCount <= Tcp4Index ) {\r
       Tcp4Index = 0;\r
-    \r
+\r
       //\r
       //  Wait for the next timer tick\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
     //  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
       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
       bTcp4Connecting = FALSE;\r
     }\r
-    \r
+\r
     //\r
     //  Open the network controller's service protocol\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
     Status = gBS->OpenProtocol (\r
                     Tcp4Controller,\r
                     &gEfiTcp4ServiceBindingProtocolGuid,\r
@@ -887,7 +1020,7 @@ Tcp4Send (
   //\r
   //  Restart the timer\r
   //\r
   //\r
   //  Restart the timer\r
   //\r
-  TimerStart ( 1000 << DATA_RATE_UPDATE_SHIFT );\r
+  TimerStart ( 1 * 1000 );\r
 \r
   //\r
   //  Initialize the packet\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.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
     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
     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
                 "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
     //\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
     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
   } 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
   @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
 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
 \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
   //\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
 \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
       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
     //\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
     }\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
       }\r
       else {\r
+        BitsPerSecond /= 1000;\r
         Average >>= 10;\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
         }\r
         else {\r
+          BitsPerSecond /= 1000;\r
           Average >>= 10;\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
           }\r
           else {\r
+            BitsPerSecond /= 1000;\r
             Average >>= 10;\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
             }\r
             else {\r
+              BitsPerSecond /= 1000;\r
               Average >>= 10;\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
             }\r
           }\r
         }\r
@@ -1499,12 +1650,15 @@ main (
   //\r
   //  Validate the command line\r
   //\r
   //\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
     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
 \r
   //\r
   //  Determine the support routines\r
@@ -1522,32 +1676,18 @@ bTcp4 = TRUE;
   //\r
   //  Use for/break instead of goto\r
   //\r
   //\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
     //\r
     //  No bytes sent so far\r
     //\r
     TotalBytesSent = 0;\r
-    AverageBytes = 0;\r
-    PreviousBytes = 0;\r
     Samples = 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
 \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
     Status = IpAddress ( );\r
     if ( EFI_ERROR ( Status )) {\r
       break;\r