]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c
Removed one include path which doesn't exist
[mirror_edk2.git] / MdeModulePkg / Universal / Network / UefiPxeBcDxe / PxeBcImpl.c
index 8d7b3d03ef2600e9c18314242759a81fc305a921..193daf1f869636fb421c83d2b801fecf2b30fefd 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2007, Intel Corporation\r
+Copyright (c) 2007 - 2008, 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
@@ -128,6 +128,11 @@ EfiPxeBcStop (
 \r
   Mode->Started = FALSE;\r
 \r
+  //\r
+  // Reset and leave joined groups\r
+  //\r
+  Private->Udp4->Groups (Private->Udp4, FALSE, NULL);\r
+\r
   Private->Udp4->Configure (Private->Udp4, NULL);\r
 \r
   Private->Dhcp4->Stop (Private->Dhcp4);\r
@@ -170,6 +175,7 @@ EfiPxeBcDhcp (
   UINT32                  DiscoverTimeout;\r
   UINTN                   Index;\r
   EFI_STATUS              Status;\r
+  EFI_ARP_CONFIG_DATA     ArpConfigData;\r
 \r
   if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -193,7 +199,7 @@ EfiPxeBcDhcp (
   //\r
   // Set the DHCP4 config data.\r
   //\r
-  NetZeroMem (&Dhcp4CfgData, sizeof (EFI_DHCP4_CONFIG_DATA));\r
+  ZeroMem (&Dhcp4CfgData, sizeof (EFI_DHCP4_CONFIG_DATA));\r
   Dhcp4CfgData.OptionCount      = OptCount;\r
   Dhcp4CfgData.OptionList       = OptList;\r
   Dhcp4CfgData.Dhcp4Callback    = PxeBcDhcpCallBack;\r
@@ -216,8 +222,8 @@ EfiPxeBcDhcp (
     //\r
     Private->NumOffers   = 0;\r
     Private->BootpIndex  = 0;\r
-    NetZeroMem (Private->ServerCount, sizeof (Private->ServerCount));\r
-    NetZeroMem (Private->ProxyIndex, sizeof (Private->ProxyIndex));\r
+    ZeroMem (Private->ServerCount, sizeof (Private->ServerCount));\r
+    ZeroMem (Private->ProxyIndex, sizeof (Private->ProxyIndex));\r
 \r
     Status = Dhcp4->Start (Dhcp4, NULL);\r
     if (EFI_ERROR (Status)) {\r
@@ -241,9 +247,9 @@ EfiPxeBcDhcp (
 \r
     ASSERT (Dhcp4Mode.State == Dhcp4Bound);\r
 \r
-    NetCopyMem (&Private->StationIp, &Dhcp4Mode.ClientAddress, sizeof (EFI_IPv4_ADDRESS));\r
-    NetCopyMem (&Private->SubnetMask, &Dhcp4Mode.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
-    NetCopyMem (&Private->GatewayIp, &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS));\r
+    CopyMem (&Private->StationIp, &Dhcp4Mode.ClientAddress, sizeof (EFI_IPv4_ADDRESS));\r
+    CopyMem (&Private->SubnetMask, &Dhcp4Mode.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
+    CopyMem (&Private->GatewayIp, &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS));\r
 \r
     //\r
     // Check the selected offer to see whether BINL is required, if no or BINL is\r
@@ -262,10 +268,25 @@ EfiPxeBcDhcp (
     //\r
     // Remove the previously configured option list and callback function\r
     //\r
-    NetZeroMem (&Dhcp4CfgData, sizeof (EFI_DHCP4_CONFIG_DATA));\r
+    ZeroMem (&Dhcp4CfgData, sizeof (EFI_DHCP4_CONFIG_DATA));\r
     Dhcp4->Configure (Dhcp4, &Dhcp4CfgData);\r
 \r
     Private->AddressIsOk = TRUE;\r
+\r
+    if (!Mode->UsingIpv6) {\r
+      //\r
+      // If in IPv4 mode, configure the corresponding ARP with this new\r
+      // station IP address.\r
+      //\r
+      ZeroMem (&ArpConfigData, sizeof (EFI_ARP_CONFIG_DATA));\r
+\r
+      ArpConfigData.SwAddressType   = 0x0800;\r
+      ArpConfigData.SwAddressLength = sizeof (EFI_IPv4_ADDRESS);\r
+      ArpConfigData.StationAddress  = &Private->StationIp.v4;\r
+\r
+      Private->Arp->Configure (Private->Arp, NULL);\r
+      Private->Arp->Configure (Private->Arp, &ArpConfigData);\r
+    }\r
   }\r
 \r
   return Status;\r
@@ -385,7 +406,7 @@ EfiPxeBcDiscover (
       //\r
       // Get the multicast discover ip address from vendor option.\r
       //\r
-      NetCopyMem (&DefaultInfo.ServerMCastIp.Addr, &VendorOpt->DiscoverMcastIp, sizeof (EFI_IPv4_ADDRESS));\r
+      CopyMem (&DefaultInfo.ServerMCastIp.Addr, &VendorOpt->DiscoverMcastIp, sizeof (EFI_IPv4_ADDRESS));\r
     }\r
 \r
     DefaultInfo.IpCnt = 0;\r
@@ -444,7 +465,7 @@ EfiPxeBcDiscover (
       if (BootSvrEntry == NULL) {\r
         Private->ServerIp.Addr[0] = SrvList[Index].IpAddr.Addr[0];\r
       } else {\r
-        NetCopyMem (&Private->ServerIp, &BootSvrEntry->IpAddr[Index], sizeof (EFI_IPv4_ADDRESS));\r
+        CopyMem (&Private->ServerIp, &BootSvrEntry->IpAddr[Index], sizeof (EFI_IPv4_ADDRESS));\r
       }\r
 \r
       Status = PxeBcDiscvBootService (\r
@@ -497,7 +518,7 @@ EfiPxeBcDiscover (
   }\r
 \r
   if (Mode->PxeBisReplyReceived) {\r
-    NetCopyMem (&Private->ServerIp, &Mode->PxeReply.Dhcpv4.BootpSiAddr, sizeof (EFI_IPv4_ADDRESS));\r
+    CopyMem (&Private->ServerIp, &Mode->PxeReply.Dhcpv4.BootpSiAddr, sizeof (EFI_IPv4_ADDRESS));\r
   }\r
 \r
   return Status;\r
@@ -568,10 +589,10 @@ EfiPxeBcMtftp (
   Mtftp4Config.TimeoutValue      = PXEBC_MTFTP_TIMEOUT;\r
   Mtftp4Config.TryCount          = PXEBC_MTFTP_RETRIES;\r
 \r
-  NetCopyMem (&Mtftp4Config.StationIp, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS));\r
-  NetCopyMem (&Mtftp4Config.SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
-  NetCopyMem (&Mtftp4Config.GatewayIp, &Private->GatewayIp, sizeof (EFI_IPv4_ADDRESS));\r
-  NetCopyMem (&Mtftp4Config.ServerIp, ServerIp, sizeof (EFI_IPv4_ADDRESS));\r
+  CopyMem (&Mtftp4Config.StationIp, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS));\r
+  CopyMem (&Mtftp4Config.SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
+  CopyMem (&Mtftp4Config.GatewayIp, &Private->GatewayIp, sizeof (EFI_IPv4_ADDRESS));\r
+  CopyMem (&Mtftp4Config.ServerIp, ServerIp, sizeof (EFI_IPv4_ADDRESS));\r
 \r
   switch (Operation) {\r
 \r
@@ -769,13 +790,13 @@ EfiPxeBcUdpWrite (
   ZeroMem (&Token, sizeof (EFI_UDP4_COMPLETION_TOKEN));\r
   ZeroMem (&Udp4Session, sizeof (EFI_UDP4_SESSION_DATA));\r
 \r
-  NetCopyMem (&Udp4Session.DestinationAddress, DestIp, sizeof (EFI_IPv4_ADDRESS));\r
+  CopyMem (&Udp4Session.DestinationAddress, DestIp, sizeof (EFI_IPv4_ADDRESS));\r
   Udp4Session.DestinationPort = *DestPort;\r
-  NetCopyMem (&Udp4Session.SourceAddress, SrcIp, sizeof (EFI_IPv4_ADDRESS));\r
+  CopyMem (&Udp4Session.SourceAddress, SrcIp, sizeof (EFI_IPv4_ADDRESS));\r
   Udp4Session.SourcePort = *SrcPort;\r
 \r
   FragCount = (HeaderSize != NULL) ? 2 : 1;\r
-  Udp4TxData = (EFI_UDP4_TRANSMIT_DATA *) NetAllocatePool (sizeof (EFI_UDP4_TRANSMIT_DATA) + (FragCount - 1) * sizeof (EFI_UDP4_FRAGMENT_DATA));\r
+  Udp4TxData = (EFI_UDP4_TRANSMIT_DATA *) AllocatePool (sizeof (EFI_UDP4_TRANSMIT_DATA) + (FragCount - 1) * sizeof (EFI_UDP4_FRAGMENT_DATA));\r
   if (Udp4TxData == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -799,7 +820,7 @@ EfiPxeBcUdpWrite (
 \r
   Status = gBS->CreateEvent (\r
                   EVT_NOTIFY_SIGNAL,\r
-                  NET_TPL_EVENT,\r
+                  TPL_NOTIFY,\r
                   PxeBcCommonNotify,\r
                   &IsDone,\r
                   &Token.Event\r
@@ -826,11 +847,67 @@ ON_EXIT:
     gBS->CloseEvent (Token.Event);\r
   }\r
 \r
-  NetFreePool (Udp4TxData);\r
+  gBS->FreePool (Udp4TxData);\r
 \r
   return Status;\r
 }\r
 \r
+/**\r
+  Validate IP packages by IP filter settings\r
+\r
+  @param  PxeBcMode          Pointer to EFI_PXEBC_MODE\r
+\r
+  @param  Session            Received UDP session\r
+\r
+  @retval TRUE               The UDP package matches IP filters\r
+\r
+  @retval FLASE              The UDP package doesn't matches IP filters\r
+\r
+**/\r
+STATIC\r
+BOOLEAN\r
+CheckIpByFilter (\r
+  EFI_PXE_BASE_CODE_MODE    *PxeBcMode,\r
+  EFI_UDP4_SESSION_DATA     *Session\r
+  )\r
+{\r
+  UINTN                   Index;\r
+  EFI_IPv4_ADDRESS        Ip4Address;\r
+  EFI_IPv4_ADDRESS        DestIp4Address;\r
+\r
+  if (PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) {\r
+    return TRUE;\r
+  }\r
+\r
+  CopyMem (&DestIp4Address, &Session->DestinationAddress, sizeof (DestIp4Address));\r
+  if ((PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST) &&\r
+      IP4_IS_MULTICAST (NTOHL (EFI_IP4 (DestIp4Address)))\r
+      ) {\r
+    return TRUE;\r
+  }\r
+\r
+  if ((PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST) &&\r
+      IP4_IS_LOCAL_BROADCAST (EFI_NTOHL (DestIp4Address))\r
+      ) {\r
+    return TRUE;\r
+  }\r
+\r
+  CopyMem (&Ip4Address, &PxeBcMode->StationIp.v4, sizeof (Ip4Address));\r
+  if ((PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) &&\r
+      EFI_IP4_EQUAL (&PxeBcMode->StationIp.v4, &DestIp4Address)\r
+      ) {\r
+    return TRUE;\r
+  }\r
+\r
+  for (Index = 0; Index < PxeBcMode->IpFilter.IpCnt; ++Index) {\r
+    CopyMem (&Ip4Address, &PxeBcMode->IpFilter.IpList[Index].v4, sizeof (Ip4Address));\r
+    if (EFI_IP4_EQUAL (&Ip4Address, &DestIp4Address)) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
 \r
 /**\r
   GC_NOTO: Add function description\r
@@ -900,10 +977,6 @@ EfiPxeBcUdpRead (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
   if ((!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && (DestPort == NULL)) ||\r
       (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && (SrcIp == NULL)) ||\r
       (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) && (SrcPort == NULL))) {\r
@@ -928,7 +1001,7 @@ EfiPxeBcUdpRead (
 \r
   Status = gBS->CreateEvent (\r
                   EVT_NOTIFY_SIGNAL,\r
-                  NET_TPL_EVENT,\r
+                  TPL_NOTIFY,\r
                   PxeBcCommonNotify,\r
                   &IsDone,\r
                   &Token.Event\r
@@ -961,23 +1034,34 @@ EfiPxeBcUdpRead (
 \r
     Matched = FALSE;\r
 \r
-    //\r
-    // Match the destination ip of the received udp dgram\r
-    //\r
-    if (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP) {\r
-      Matched = TRUE;\r
-\r
-      if (DestIp != NULL) {\r
-        NetCopyMem (DestIp, &Session->DestinationAddress, sizeof (EFI_IPv4_ADDRESS));\r
+    if (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER) {\r
+      //\r
+      // Check UDP package by IP filter settings\r
+      //\r
+      if (CheckIpByFilter (Mode, Session)) {\r
+        Matched = TRUE;\r
       }\r
-    } else {\r
-      if (DestIp != NULL) {\r
-        if (EFI_IP4_EQUAL (DestIp, &Session->DestinationAddress)) {\r
-          Matched = TRUE;\r
+    }\r
+\r
+    if (Matched) {\r
+      //\r
+      // Match the destination ip of the received udp dgram\r
+      //\r
+      if (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP) {\r
+        Matched = TRUE;\r
+\r
+        if (DestIp != NULL) {\r
+          CopyMem (DestIp, &Session->DestinationAddress, sizeof (EFI_IPv4_ADDRESS));\r
         }\r
       } else {\r
-        if (EFI_IP4_EQUAL (&Private->StationIp, &Session->DestinationAddress)) {\r
-          Matched = TRUE;\r
+        if (DestIp != NULL) {\r
+          if (EFI_IP4_EQUAL (DestIp, &Session->DestinationAddress)) {\r
+            Matched = TRUE;\r
+          }\r
+        } else {\r
+          if (EFI_IP4_EQUAL (&Private->StationIp, &Session->DestinationAddress)) {\r
+            Matched = TRUE;\r
+          }\r
         }\r
       }\r
     }\r
@@ -1006,7 +1090,7 @@ EfiPxeBcUdpRead (
       if (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP) {\r
 \r
         if (SrcIp != NULL) {\r
-          NetCopyMem (SrcIp, &Session->SourceAddress, sizeof (EFI_IPv4_ADDRESS));\r
+          CopyMem (SrcIp, &Session->SourceAddress, sizeof (EFI_IPv4_ADDRESS));\r
         }\r
       } else {\r
 \r
@@ -1039,7 +1123,7 @@ EfiPxeBcUdpRead (
 \r
       if (HeaderSize != NULL) {\r
         CopyLen = MIN (*HeaderSize, RxData->DataLength);\r
-        NetCopyMem (HeaderPtr, RxData->FragmentTable[0].FragmentBuffer, CopyLen);\r
+        CopyMem (HeaderPtr, RxData->FragmentTable[0].FragmentBuffer, CopyLen);\r
         *HeaderSize = CopyLen;\r
       }\r
 \r
@@ -1049,7 +1133,7 @@ EfiPxeBcUdpRead (
       } else {\r
 \r
         *BufferSize = RxData->DataLength - CopyLen;\r
-        NetCopyMem (BufferPtr, (UINT8 *) RxData->FragmentTable[0].FragmentBuffer + CopyLen, *BufferSize);\r
+        CopyMem (BufferPtr, (UINT8 *) RxData->FragmentTable[0].FragmentBuffer + CopyLen, *BufferSize);\r
       }\r
     } else {\r
 \r
@@ -1091,7 +1175,120 @@ EfiPxeBcSetIpFilter (
   IN EFI_PXE_BASE_CODE_IP_FILTER      *NewFilter\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  EFI_STATUS                Status;\r
+  PXEBC_PRIVATE_DATA        *Private;\r
+  EFI_PXE_BASE_CODE_MODE    *Mode;\r
+  UINTN                     Index;\r
+  BOOLEAN                   PromiscuousNeed;\r
+\r
+  if (This == NULL) {\r
+    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL.\n"));\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);\r
+  Mode = Private->PxeBc.Mode;\r
+\r
+  if (Private == NULL) {\r
+    DEBUG ((EFI_D_ERROR, "PXEBC_PRIVATE_DATA poiner == NULL.\n"));\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (NewFilter == NULL) {\r
+    DEBUG ((EFI_D_ERROR, "IP Filter *NewFilter == NULL.\n"));\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (!Mode->Started) {\r
+    DEBUG ((EFI_D_ERROR, "BC was not started.\n"));\r
+    return EFI_NOT_STARTED;\r
+  }\r
+\r
+  PromiscuousNeed = FALSE;\r
+  for (Index = 0; Index < NewFilter->IpCnt; ++Index) {\r
+    if (IP4_IS_LOCAL_BROADCAST (EFI_IP4 (NewFilter->IpList[Index].v4))) {\r
+      //\r
+      // The IP is a broadcast address.\r
+      //\r
+      DEBUG ((EFI_D_ERROR, "There is broadcast address in NewFilter.\n"));\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    if (Ip4IsUnicast (EFI_IP4 (NewFilter->IpList[Index].v4), 0) &&\r
+        (NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP)\r
+       ) {\r
+      //\r
+      // If EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP is set and IP4 address is in IpList,\r
+      // promiscuous mode is needed.\r
+      //\r
+      PromiscuousNeed = TRUE;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Clear the UDP instance configuration, all joined groups will be left\r
+  // during the operation.\r
+  //\r
+  Private->Udp4->Configure (Private->Udp4, NULL);\r
+  Private->Udp4CfgData.AcceptPromiscuous  = FALSE;\r
+  Private->Udp4CfgData.AcceptBroadcast    = FALSE;\r
+\r
+  if (PromiscuousNeed ||\r
+      NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS ||\r
+      NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST\r
+     ) {\r
+    //\r
+    // Configure the udp4 filter to receive all packages\r
+    //\r
+    Private->Udp4CfgData.AcceptPromiscuous  = TRUE;\r
+\r
+    //\r
+    // Configure the UDP instance with the new configuration.\r
+    //\r
+    Status = Private->Udp4->Configure (Private->Udp4, &Private->Udp4CfgData);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+  } else {\r
+\r
+    if (NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST) {\r
+      //\r
+      // Configure the udp4 filter to receive all broadcast packages\r
+      //\r
+      Private->Udp4CfgData.AcceptBroadcast    = TRUE;\r
+    }\r
+\r
+    //\r
+    // Configure the UDP instance with the new configuration.\r
+    //\r
+    Status = Private->Udp4->Configure (Private->Udp4, &Private->Udp4CfgData);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    if (NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) {\r
+\r
+      for (Index = 0; Index < NewFilter->IpCnt; ++Index) {\r
+        if (IP4_IS_MULTICAST (EFI_NTOHL (NewFilter->IpList[Index].v4))) {\r
+          //\r
+          // Join the mutilcast group\r
+          //\r
+          Status = Private->Udp4->Groups (Private->Udp4, TRUE, &NewFilter->IpList[Index].v4);\r
+          if (EFI_ERROR (Status)) {\r
+            return Status;\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+\r
+  //\r
+  // Save the new filter.\r
+  //\r
+  CopyMem (&Mode->IpFilter, NewFilter, sizeof (Mode->IpFilter));\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 \r
@@ -1117,10 +1314,44 @@ EfiPxeBcArp (
   IN EFI_MAC_ADDRESS                  * MacAddr OPTIONAL\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  PXEBC_PRIVATE_DATA      *Private;\r
+  EFI_PXE_BASE_CODE_MODE  *Mode;\r
+  EFI_STATUS              Status;\r
+  EFI_MAC_ADDRESS         TempMacAddr;\r
+\r
+  if (This == NULL || IpAddr == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);\r
+  Mode    = Private->PxeBc.Mode;\r
+\r
+  if (!Mode->Started) {\r
+    return EFI_NOT_STARTED;\r
+  }\r
+\r
+  if (!Private->AddressIsOk || Mode->UsingIpv6) {\r
+    //\r
+    // We can't resolve the IP address if we don't have a local address now.\r
+    // Don't have ARP for IPv6.\r
+    //\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = Private->Arp->Request (Private->Arp, &IpAddr->v4, NULL, &TempMacAddr);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (MacAddr != NULL) {\r
+    CopyMem (MacAddr, &TempMacAddr, sizeof (EFI_MAC_ADDRESS));\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 \r
+\r
 /**\r
   GC_NOTO: Add function description\r
 \r
@@ -1266,6 +1497,7 @@ EfiPxeBcSetStationIP (
 {\r
   PXEBC_PRIVATE_DATA      *Private;\r
   EFI_PXE_BASE_CODE_MODE  *Mode;\r
+  EFI_ARP_CONFIG_DATA     ArpConfigData;\r
 \r
   if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1296,6 +1528,21 @@ EfiPxeBcSetStationIP (
 \r
   Private->AddressIsOk = TRUE;\r
 \r
+  if (!Mode->UsingIpv6) {\r
+    //\r
+    // If in IPv4 mode, configure the corresponding ARP with this new\r
+    // station IP address.\r
+    //\r
+    ZeroMem (&ArpConfigData, sizeof (EFI_ARP_CONFIG_DATA));\r
+\r
+    ArpConfigData.SwAddressType   = 0x0800;\r
+    ArpConfigData.SwAddressLength = sizeof (EFI_IPv4_ADDRESS);\r
+    ArpConfigData.StationAddress  = &Private->StationIp.v4;\r
+\r
+    Private->Arp->Configure (Private->Arp, NULL);\r
+    Private->Arp->Configure (Private->Arp, &ArpConfigData);\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -1397,27 +1644,27 @@ EfiPxeBcSetPackets (
   }\r
 \r
   if (NewDhcpDiscover != NULL) {\r
-    NetCopyMem (&Mode->DhcpDiscover, NewDhcpDiscover, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
+    CopyMem (&Mode->DhcpDiscover, NewDhcpDiscover, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
   }\r
 \r
   if (NewDhcpAck != NULL) {\r
-    NetCopyMem (&Mode->DhcpAck, NewDhcpAck, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
+    CopyMem (&Mode->DhcpAck, NewDhcpAck, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
   }\r
 \r
   if (NewProxyOffer != NULL) {\r
-    NetCopyMem (&Mode->ProxyOffer, NewProxyOffer, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
+    CopyMem (&Mode->ProxyOffer, NewProxyOffer, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
   }\r
 \r
   if (NewPxeDiscover != NULL) {\r
-    NetCopyMem (&Mode->PxeDiscover, NewPxeDiscover, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
+    CopyMem (&Mode->PxeDiscover, NewPxeDiscover, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
   }\r
 \r
   if (NewPxeReply != NULL) {\r
-    NetCopyMem (&Mode->PxeReply, NewPxeReply, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
+    CopyMem (&Mode->PxeReply, NewPxeReply, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
   }\r
 \r
   if (NewPxeBisReply != NULL) {\r
-    NetCopyMem (&Mode->PxeBisReply, NewPxeBisReply, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
+    CopyMem (&Mode->PxeBisReply, NewPxeBisReply, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -1623,12 +1870,12 @@ DiscoverBootFile (
     Packet = &Private->Dhcp4Ack;\r
   }\r
 \r
-  NetCopyMem (&Private->ServerIp, &Packet->Packet.Offer.Dhcp4.Header.ServerAddr, sizeof (EFI_IPv4_ADDRESS));\r
+  CopyMem (&Private->ServerIp, &Packet->Packet.Offer.Dhcp4.Header.ServerAddr, sizeof (EFI_IPv4_ADDRESS));\r
   if (Private->ServerIp.Addr[0] == 0) {\r
     //\r
     // next server ip address is zero, use option 54 instead\r
     //\r
-    NetCopyMem (\r
+    CopyMem (\r
       &Private->ServerIp,\r
       Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_SERVER_ID]->Data,\r
       sizeof (EFI_IPv4_ADDRESS)\r
@@ -1646,7 +1893,7 @@ DiscoverBootFile (
     //\r
     // Already have the bootfile length option, compute the file size\r
     //\r
-    NetCopyMem (&Value, Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_BOOTFILE_LEN]->Data, sizeof (Value));\r
+    CopyMem (&Value, Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_BOOTFILE_LEN]->Data, sizeof (Value));\r
     Value       = NTOHS (Value);\r
     *BufferSize = 512 * Value;\r
     Status      = EFI_BUFFER_TOO_SMALL;\r