Index: ArpImpl.c
===================================================================
--- ArpImpl.c	(revision 13807)
+++ ArpImpl.c	(working copy)
@@ -280,7 +280,7 @@
     // Send back the ARP Reply. If we reach here, Instance is not NULL and CacheEntry
     // is not NULL.
     //
-    ArpSendFrame (Instance, CacheEntry, ARP_OPCODE_REPLY);
+    ArpSendFrame (Instance, CacheEntry, ARP_OPCODE_REPLY, 0);
   }
 
 RECYCLE_RXDATA:
@@ -447,7 +447,7 @@
         ContextEntry   = CacheEntry->UserRequestList.ForwardLink;
         RequestContext = NET_LIST_USER_STRUCT (ContextEntry, USER_REQUEST_CONTEXT, List);
 
-        ArpSendFrame (RequestContext->Instance, CacheEntry, ARP_OPCODE_REQUEST);
+        ArpSendFrame (RequestContext->Instance, CacheEntry, ARP_OPCODE_REQUEST, 0);
 
         CacheEntry->RetryCount--;
         CacheEntry->NextRetryTime = RequestContext->Instance->ConfigData.RetryTimeOut;
@@ -963,6 +963,11 @@
       // Set the state to configured.
       //
       Instance->Configured = TRUE;
+
+      //NOTE: This currently does NOT follow RFC 5227 2.3 exactly
+	    //ARP Announce
+      ArpAnnouncement( Instance );
+
     }
 
     //
@@ -999,7 +1004,46 @@
   return EFI_SUCCESS;
 }
 
+/** 
+  This function sends an ARP announcement that the host is going to use the currently
+  configured IPv4 address, this also clears out any stale ARP cache entries left over
+  from previously configured hosts on the subnet. [RFC 5227 2.3. Announcing an Address]
 
+  @param  Instance              Pointer to the current intance data
+
+  @retval 
+**/
+VOID
+ArpAnnouncement(
+  IN ARP_INSTANCE_DATA    *Instance
+  ) {
+  ARP_CACHE_ENTRY           AnnouncementEntry;
+  EFI_SIMPLE_NETWORK_MODE   *SnpMode;
+
+  SnpMode = &Instance->ArpService->SnpMode;
+
+  AnnouncementEntry.Addresses[0].AddressPtr = AnnouncementEntry.Addresses[0].Buffer.ProtoAddress;
+  AnnouncementEntry.Addresses[1].AddressPtr = AnnouncementEntry.Addresses[1].Buffer.ProtoAddress;
+
+  // fabricate an entry that will result in an ARP "Request" containing our MAC->IP info in target and source
+
+  ZeroMem( AnnouncementEntry.Addresses[Hardware].AddressPtr, SnpMode->HwAddressSize );
+
+  CopyMem(
+   AnnouncementEntry.Addresses[Hardware].AddressPtr,
+    &SnpMode->CurrentAddress,
+    SnpMode->HwAddressSize);
+
+  CopyMem (
+    AnnouncementEntry.Addresses[Protocol].AddressPtr,
+    Instance->ConfigData.StationAddress,
+    Instance->ConfigData.SwAddressLength
+    );
+
+  ArpSendFrame (Instance, &AnnouncementEntry, ARP_OPCODE_REQUEST, 1);
+}
+
+
 /**
   Send out an arp frame using the CachEntry and the ArpOpCode.
 
@@ -1009,6 +1053,17 @@
   @param[in]  ArpOpCode              The opcode used to send out this Arp frame, either
                                      request or reply.
 
+  @param[in]  Announce               Specifies if the frame is an announcement packet
+                                     If set to 0: [Normal ARP packet]
+                                     Packet is left untouched
+
+                                     If set to 1: [ARP Announce Packet]
+                                     Sender MAC set to all 0's
+
+                                     If set to 2: [ARP DAD Probe Packet]
+                                     Sender MAC set to all 0's
+                                     Sender IP  set to all 0's
+
   @return None.
 
 **/
@@ -1016,7 +1071,8 @@
 ArpSendFrame (
   IN ARP_INSTANCE_DATA  *Instance,
   IN ARP_CACHE_ENTRY    *CacheEntry,
-  IN UINT16             ArpOpCode
+  IN UINT16             ArpOpCode,
+  IN UINT16             Announce
   )
 {
   EFI_STATUS                            Status;
@@ -1136,19 +1192,21 @@
   //
   // The sender protocol address.
   //
-  CopyMem (TmpPtr, ConfigData->StationAddress, ConfigData->SwAddressLength);
+  if ( Announce == 0 || Announce == 1 ) CopyMem (TmpPtr, ConfigData->StationAddress, ConfigData->SwAddressLength);
+  else ZeroMem(TmpPtr, ConfigData->SwAddressLength);
   TmpPtr += ConfigData->SwAddressLength;
 
   //
   // The target hardware address.
   //
+  if ( Announce == 0)
   CopyMem (
     TmpPtr,
     CacheEntry->Addresses[Hardware].AddressPtr,
     SnpMode->HwAddressSize
     );
+  else ZeroMem(TmpPtr, SnpMode->HwAddressSize);
   TmpPtr += SnpMode->HwAddressSize;
-
   //
   // The target protocol address.
   //
Index: ArpImpl.h
===================================================================
--- ArpImpl.h	(revision 13807)
+++ ArpImpl.h	(working copy)
@@ -260,7 +260,32 @@
   IN EFI_ARP_CONFIG_DATA  *ConfigData OPTIONAL
   );
 
+/** 
+  This function sends an ARP announcement that the host is going to use the currently
+  configured IPv4 address, this also clears out any stale ARP cache entries left over
+  from previously configured hosts on the subnet. [RFC 5227 2.3. Announcing an Address]
+
+  @param  Instance              Pointer to the current intance data
+
+  @retval 
+**/
+VOID
+ArpAnnouncement(
+  IN ARP_INSTANCE_DATA    *Instance
+  );
+
 /**
+  This function sends an ARP probe to check if other devices are using the currently
+  configured address. Used to implement RFC 5227 2.1.
+
+**/
+EFI_STATUS
+EFIAPI
+ArpProbe (
+  IN ARP_INSTANCE_DATA    *Instance
+  );
+
+/**
   This function is used to insert entries into the ARP cache.
 
   ARP cache entries are typically inserted and updated by network protocol drivers 
@@ -613,6 +638,17 @@
   @param[in]  ArpOpCode              The opcode used to send out this Arp frame, either
                                      request or reply.
 
+  @param[in]  Announce               Specifies if the frame is an announcement packet
+                                     If set to 0: [Normal ARP packet]
+                                     Packet is left untouched
+
+                                     If set to 1: [ARP Announce Packet]
+                                     Sender MAC set to all 0's
+
+                                     If set to 2: [ARP DAD Probe Packet]
+                                     Sender MAC set to all 0's
+                                     Sender IP  set to all 0's
+
   @return None.
 
 **/
@@ -620,7 +656,8 @@
 ArpSendFrame (
   IN ARP_INSTANCE_DATA  *Instance,
   IN ARP_CACHE_ENTRY    *CacheEntry,
-  IN UINT16             ArpOpCode
+  IN UINT16             ArpOpCode,
+  IN UINT16             Announce
   );
 
 /**
Index: ArpMain.c
===================================================================
--- ArpMain.c	(revision 13807)
+++ ArpMain.c	(working copy)
@@ -653,7 +653,7 @@
   //
   // Send out the ARP Request frame.
   //
-  ArpSendFrame (Instance, CacheEntry, ARP_OPCODE_REQUEST);
+  ArpSendFrame (Instance, CacheEntry, ARP_OPCODE_REQUEST, 0);
   Status = EFI_NOT_READY;
 
 UNLOCK_EXIT:
