Index: trunk/src/VBox/Devices/Network/slirp/bootp.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/bootp.c	(revision 22495)
+++ trunk/src/VBox/Devices/Network/slirp/bootp.c	(revision 22500)
@@ -47,5 +47,5 @@
     return NULL; 
 }
-BOOTPClient *bc_alloc_client(PNATState pData)
+static BOOTPClient *bc_alloc_client(PNATState pData)
 {
     int i;
@@ -428,4 +428,5 @@
                memcpy(bc->macaddr, bp->bp_hwaddr, bp->bp_hlen);
                bc->addr.s_addr = bp->bp_ciaddr.s_addr; 
+               slirp_update_arp_cache(pData, bp->bp_ciaddr.s_addr, bp->bp_hwaddr);
             }
         }
@@ -450,4 +451,5 @@
             memcpy(bc->macaddr, bp->bp_hwaddr, bp->bp_hlen);
             bc->addr.s_addr = ui32; 
+            slirp_update_arp_cache(pData, bp->bp_ciaddr.s_addr, bp->bp_hwaddr);
         break;
         case NONE:
Index: trunk/src/VBox/Devices/Network/slirp/bootp.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/bootp.h	(revision 22495)
+++ trunk/src/VBox/Devices/Network/slirp/bootp.h	(revision 22500)
@@ -133,3 +133,2 @@
 
 void bootp_input(PNATState, struct mbuf *m);
-BOOTPClient *bc_alloc_client(PNATState pData);
Index: trunk/src/VBox/Devices/Network/slirp/ip_output.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/ip_output.c	(revision 22495)
+++ trunk/src/VBox/Devices/Network/slirp/ip_output.c	(revision 22500)
@@ -49,4 +49,5 @@
 {
     int i;
+    struct arp_cache_entry *ac = NULL;
    /* @todo (vasily) to quick ramp up on routing rails
     * we use information from DHCP server leasings, this
@@ -54,4 +55,9 @@
     * and should be borrowed from other places
     */
+    LIST_FOREACH(ac, &pData->arp_cache, list)
+    {
+        if (ac->ip == dst)
+            return &ac->ether[0];
+    }
     for (i = 0; i < NB_ADDR; i++)
     {
Index: trunk/src/VBox/Devices/Network/slirp/slirp.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/slirp.c	(revision 22495)
+++ trunk/src/VBox/Devices/Network/slirp/slirp.c	(revision 22500)
@@ -637,8 +637,15 @@
     ftp_alias_unload(pData);
     nbt_alias_unload(pData);
-    while(!LIST_EMPTY(&instancehead)) {
+    while(!LIST_EMPTY(&instancehead)) 
+    {
         struct libalias *la = LIST_FIRST(&instancehead);
         /* libalias do all clean up */
         LibAliasUninit(la);
+    }
+    while(!LIST_EMPTY(&pData->arp_cache)) 
+    {
+        struct arp_cache_entry *ac = LIST_FIRST(&pData->arp_cache);
+        LIST_REMOVE(ac, list);
+        RTMemFree(ac);
     }
 #ifdef RT_OS_WINDOWS
@@ -1371,11 +1378,18 @@
             break;
         case ARPOP_REPLY:
-        /* @todo check if we already have requested address */
-        /* if no*/
-        {
-            BOOTPClient *bc = bc_alloc_client(pData);
-            bc->addr.s_addr = *(uint32_t *)ah->ar_sip;
-            memcpy(bc->macaddr, ah->ar_sha, ETH_ALEN);
-            m_free(pData, m);
+        {
+            struct arp_cache_entry *ac = NULL;
+            if (slirp_update_arp_cache(pData, ah->ar_sip, ah->ar_sha) == 0)
+                break;
+            ac = RTMemAllocZ(sizeof(struct arp_cache_entry));
+            if (ac == NULL)
+            {
+                LogRel(("NAT: Can´t allocate arp cache entry\n"));
+                m_free(pData, m);
+                return;
+            }
+            ac->ip = *(uint32_t *)ah->ar_sip;
+            memcpy(ac->ether, ah->ar_sha, ETH_ALEN);
+            LIST_INSERT_HEAD(&pData->arp_cache, ac, list);
         }
         break;
@@ -1825,2 +1839,19 @@
     LogRel(("NAT: ARP request sent\n"));
 }
+/* updates the arp cache 
+ * @returns 0 - if has found and updated
+ *          1 - if hasn´t found.
+ */
+int slirp_update_arp_cache(PNATState pData, uint32_t dst, const uint8_t *mac)
+{
+    struct arp_cache_entry *ac;
+    LIST_FOREACH(ac, &pData->arp_cache, list)
+    {
+        if (memcmp(ac->ether, mac, ETH_ALEN) == 0)
+        {
+            ac->ip = dst;
+            return 0;
+        }
+    }
+    return 1;
+}
Index: trunk/src/VBox/Devices/Network/slirp/slirp.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/slirp.h	(revision 22495)
+++ trunk/src/VBox/Devices/Network/slirp/slirp.h	(revision 22500)
@@ -310,4 +310,5 @@
 /*slirp.c*/
 void slirp_arp_who_has(PNATState pData, uint32_t dst);
+int slirp_update_arp_cache(PNATState pData, uint32_t dst, const uint8_t *mac);
 #define MIN_MRU 128
 #define MAX_MRU 16384
Index: trunk/src/VBox/Devices/Network/slirp/slirp_state.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/slirp_state.h	(revision 22495)
+++ trunk/src/VBox/Devices/Network/slirp/slirp_state.h	(revision 22500)
@@ -38,4 +38,17 @@
 /** DHCP Lease time. */
 #define LEASE_TIME (24 * 3600)
+
+/*
+ * ARP cache this is naive implementaion of ARP 
+ * cache of mapping 4 byte IPv4 address to 6 byte 
+ * ethernet one.
+ */
+struct arp_cache_entry
+{
+    uint32_t ip;
+    uint8_t ether[6];
+    LIST_ENTRY(arp_cache_entry) list;
+};
+LIST_HEAD(arp_cache_head, arp_cache_entry);
 
 /** TFTP session entry. */
@@ -241,4 +254,5 @@
     struct port_forward_rule_list port_forward_rule_head;
     int port_forwarding_activated;
+    struct arp_cache_head arp_cache;
     /*libalis modules' handlers*/
     struct proto_handler *ftp_module;
