Index: trunk/src/VBox/Devices/Network/DrvNAT.cpp
===================================================================
--- trunk/src/VBox/Devices/Network/DrvNAT.cpp	(revision 527)
+++ trunk/src/VBox/Devices/Network/DrvNAT.cpp	(revision 530)
@@ -243,4 +243,8 @@
 {
     LogFlow(("drvNATDestruct:\n"));
+#if ARCH_BITS == 64
+    LogRel(("NAT: g_cpvHashUsed=%RU32 g_cpvHashCollisions=%RU32 g_cpvHashInserts=%RU64 g_cpvHashDone=%RU64\n",
+            g_cpvHashUsed, g_cpvHashCollisions, g_cpvHashInserts, g_cpvHashDone));
+#endif 
     slirp_term();
     g_pDrv = NULL;
Index: trunk/src/VBox/Devices/Network/slirp/ip_input.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/ip_input.c	(revision 527)
+++ trunk/src/VBox/Devices/Network/slirp/ip_input.c	(revision 530)
@@ -57,5 +57,5 @@
 ip_init()
 {
-	ipq.next = ipq.prev = (ipqp_32)&ipq;
+	ipq.next = ipq.prev = ptr_to_u32(&ipq);
 	ip_id = tt.tv_sec & 0xffff;
 	udp_init();
@@ -164,6 +164,6 @@
 		 * of this datagram.
 		 */
-		for (fp = (struct ipq *) ipq.next; fp != &ipq;
-		     fp = (struct ipq *) fp->next)
+		for (fp = u32_to_ptr(ipq.next, struct ipq *); fp != &ipq;
+		     fp = u32_to_ptr(fp->next, struct ipq *))
 		  if (ip->ip_id == fp->ipq_id &&
 		      ip->ip_src.s_addr == fp->ipq_src.s_addr &&
@@ -270,5 +270,5 @@
 	  fp->ipq_p = ip->ip_p;
 	  fp->ipq_id = ip->ip_id;
-	  fp->ipq_next = fp->ipq_prev = (ipasfragp_32)fp;
+	  fp->ipq_next = fp->ipq_prev = ptr_to_u32((struct ipasfrag *)fp);
 	  fp->ipq_src = ((struct ip *)ip)->ip_src;
 	  fp->ipq_dst = ((struct ip *)ip)->ip_dst;
@@ -280,6 +280,6 @@
 	 * Find a segment which begins after this one does.
 	 */
-	for (q = (struct ipasfrag *)fp->ipq_next; q != (struct ipasfrag *)fp;
-	    q = (struct ipasfrag *)q->ipf_next)
+	for (q = u32_to_ptr(fp->ipq_next, struct ipasfrag *); q != (struct ipasfrag *)fp;
+	    q = u32_to_ptr(q->ipf_next, struct ipasfrag *))
 		if (q->ip_off > ip->ip_off)
 			break;
@@ -290,7 +290,7 @@
 	 * segment.  If it provides all of our data, drop us.
 	 */
-	if (q->ipf_prev != (ipasfragp_32)fp) {
-		i = ((struct ipasfrag *)(q->ipf_prev))->ip_off +
-		  ((struct ipasfrag *)(q->ipf_prev))->ip_len - ip->ip_off;
+	if (u32_to_ptr(q->ipf_prev, struct ipq *) != fp) {
+		i = (u32_to_ptr(q->ipf_prev, struct ipasfrag *))->ip_off +
+		  (u32_to_ptr(q->ipf_prev, struct ipasfrag *))->ip_len - ip->ip_off;
 		if (i > 0) {
 			if (i >= ip->ip_len)
@@ -314,7 +314,7 @@
 			break;
 		}
-		q = (struct ipasfrag *) q->ipf_next;
-		m_freem(dtom((struct ipasfrag *) q->ipf_prev));
-		ip_deq((struct ipasfrag *) q->ipf_prev);
+		q = u32_to_ptr(q->ipf_next, struct ipasfrag *);
+		m_freem(dtom(u32_to_ptr(q->ipf_prev, struct ipasfrag *)));
+		ip_deq(u32_to_ptr(q->ipf_prev, struct ipasfrag *));
 	}
 
@@ -324,13 +324,13 @@
 	 * check for complete reassembly.
 	 */
-	ip_enq(ip, (struct ipasfrag *) q->ipf_prev);
+	ip_enq(ip, u32_to_ptr(q->ipf_prev, struct ipasfrag *));
 	next = 0;
-	for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp;
-	     q = (struct ipasfrag *) q->ipf_next) {
+	for (q = u32_to_ptr(fp->ipq_next, struct ipasfrag *); q != (struct ipasfrag *)fp;
+	     q = u32_to_ptr(q->ipf_next, struct ipasfrag *)) {
 		if (q->ip_off != next)
 			return (0);
 		next += q->ip_len;
 	}
-	if (((struct ipasfrag *)(q->ipf_prev))->ipf_mff & 1)
+	if (u32_to_ptr(q->ipf_prev, struct ipasfrag *)->ipf_mff & 1)
 		return (0);
 
@@ -338,12 +338,12 @@
 	 * Reassembly is complete; concatenate fragments.
 	 */
-	q = (struct ipasfrag *) fp->ipq_next;
+	q = u32_to_ptr(fp->ipq_next, struct ipasfrag *);
 	m = dtom(q);
 
-	q = (struct ipasfrag *) q->ipf_next;
+	q = u32_to_ptr(q->ipf_next, struct ipasfrag *);
 	while (q != (struct ipasfrag *)fp) {
 	  struct mbuf *t;
 	  t = dtom(q);
-	  q = (struct ipasfrag *) q->ipf_next;
+	  q = u32_to_ptr(q->ipf_next, struct ipasfrag *);
 	  m_cat(m, t);
 	}
@@ -355,5 +355,5 @@
 	 * Make header visible.
 	 */
-	ip = (struct ipasfrag *) fp->ipq_next;
+	ip = u32_to_ptr(fp->ipq_next, struct ipasfrag *);
 
 	/*
@@ -401,7 +401,7 @@
 	register struct ipasfrag *q, *p;
 
-	for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp;
+	for (q = u32_to_ptr(fp->ipq_next, struct ipasfrag *); q != (struct ipasfrag *)fp;
 	    q = p) {
-		p = (struct ipasfrag *) q->ipf_next;
+		p = u32_to_ptr(q->ipf_next, struct ipasfrag *);
 		ip_deq(q);
 		m_freem(dtom(q));
@@ -421,8 +421,8 @@
 	DEBUG_CALL("ip_enq");
 	DEBUG_ARG("prev = %lx", (long)prev);
-	p->ipf_prev = (ipasfragp_32) prev;
+	p->ipf_prev = ptr_to_u32(prev);
 	p->ipf_next = prev->ipf_next;
-	((struct ipasfrag *)(prev->ipf_next))->ipf_prev = (ipasfragp_32) p;
-	prev->ipf_next = (ipasfragp_32) p;
+	u32_to_ptr(prev->ipf_next, struct ipasfrag *)->ipf_prev = ptr_to_u32(p);
+	prev->ipf_next = ptr_to_u32(p);
 }
 
@@ -434,6 +434,9 @@
 	register struct ipasfrag *p;
 {
-	((struct ipasfrag *)(p->ipf_prev))->ipf_next = p->ipf_next;
-	((struct ipasfrag *)(p->ipf_next))->ipf_prev = p->ipf_prev;
+	struct ipasfrag *prev = u32_to_ptr(p->ipf_prev, struct ipasfrag *);
+	struct ipasfrag *next = u32_to_ptr(p->ipf_next, struct ipasfrag *);
+	u32ptr_done(prev->ipf_next, p);
+	prev->ipf_next = p->ipf_next;
+	next->ipf_prev = p->ipf_prev;
 }
 
@@ -450,5 +453,5 @@
 	DEBUG_CALL("ip_slowtimo");
 	
-	fp = (struct ipq *) ipq.next;
+	fp = u32_to_ptr(ipq.next, struct ipq *);
 	if (fp == 0)
 	   return;
@@ -456,8 +459,8 @@
 	while (fp != &ipq) {
 		--fp->ipq_ttl;
-		fp = (struct ipq *) fp->next;
-		if (((struct ipq *)(fp->prev))->ipq_ttl == 0) {
+		fp = u32_to_ptr(fp->next, struct ipq *);
+		if (u32_to_ptr(fp->prev, struct ipq *)->ipq_ttl == 0) {
 			ipstat.ips_fragtimeout++;
-			ip_freef((struct ipq *) fp->prev);
+			ip_freef(u32_to_ptr(fp->prev, struct ipq *));
 		}
 	}
Index: trunk/src/VBox/Devices/Network/slirp/libslirp.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/libslirp.h	(revision 527)
+++ trunk/src/VBox/Devices/Network/slirp/libslirp.h	(revision 530)
@@ -34,4 +34,10 @@
 void slirp_link_up(void);
 void slirp_link_down(void);
+# if ARCH_BITS == 64
+extern uint32_t g_cpvHashUsed;
+extern uint32_t g_cpvHashCollisions;
+extern uint64_t g_cpvHashInserts;
+extern uint64_t g_cpvHashDone;
+# endif 
 #endif /* VBOX */
 
Index: trunk/src/VBox/Devices/Network/slirp/mbuf.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/mbuf.c	(revision 527)
+++ trunk/src/VBox/Devices/Network/slirp/mbuf.c	(revision 530)
@@ -110,7 +110,11 @@
 	 */
 	if (m->m_flags & M_DOFREE) {
+		u32ptr_done(ptr_to_u32(ptr), m);
 		free(m);
 		mbuf_alloced--;
 	} else if ((m->m_flags & M_FREELIST) == 0) {
+#if DEBUG_bird
+/*		u32ptr_done(ptr_to_u32(ptr), m);*/
+#endif
 		insque(m,&m_freelist);
 		m->m_flags = M_FREELIST; /* Clobber other flags */
Index: trunk/src/VBox/Devices/Network/slirp/misc.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/misc.c	(revision 527)
+++ trunk/src/VBox/Devices/Network/slirp/misc.c	(revision 530)
@@ -113,9 +113,10 @@
 	register struct quehead_32 *element = (struct quehead_32 *) a;
 	register struct quehead_32 *head = (struct quehead_32 *) b;
+	struct quehead_32 *link = u32_to_ptr(head->qh_link, struct quehead_32 *);
+
 	element->qh_link = head->qh_link;
-	head->qh_link = (u_int32_t)element;
-	element->qh_rlink = (u_int32_t)head;
-	((struct quehead_32 *)(element->qh_link))->qh_rlink
-	= (u_int32_t)element;
+	element->qh_rlink = ptr_to_u32(head);
+        Assert(link->qh_rlink == element->qh_rlink);
+	link->qh_rlink = head->qh_link = ptr_to_u32(element);
 }
 
@@ -125,6 +126,10 @@
 {
 	register struct quehead_32 *element = (struct quehead_32 *) a;
-	((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink;
-	((struct quehead_32 *)(element->qh_rlink))->qh_link = element->qh_link;
+	struct quehead_32 *link = u32_to_ptr(element->qh_link, struct quehead_32 *);
+	struct quehead_32 *rlink = u32_to_ptr(element->qh_rlink, struct quehead_32 *);
+
+	u32ptr_done(link->qh_rlink, element);
+	link->qh_rlink = element->qh_rlink;
+	rlink->qh_link = element->qh_link;
 	element->qh_rlink = 0;
 }
Index: trunk/src/VBox/Devices/Network/slirp/slirp.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/slirp.c	(revision 527)
+++ trunk/src/VBox/Devices/Network/slirp/slirp.c	(revision 530)
@@ -355,5 +355,5 @@
 		 */
 		do_slowtimo = ((tcb.so_next != &tcb) ||
-			       ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next));
+			       ((struct ipasfrag *)&ipq != u32_to_ptr(ipq.next, struct ipasfrag *)));
 		
 		for (so = tcb.so_next; so != &tcb; so = so_next) {
Index: trunk/src/VBox/Devices/Network/slirp/tcp_input.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/tcp_input.c	(revision 527)
+++ trunk/src/VBox/Devices/Network/slirp/tcp_input.c	(revision 530)
@@ -72,5 +72,5 @@
 #define TCP_REASS(tp, ti, m, so, flags) {\
        if ((ti)->ti_seq == (tp)->rcv_nxt && \
-           (tp)->seg_next == (tcpiphdrp_32)(tp) && \
+           u32_to_ptr((tp)->seg_next, struct tcpcb *) == (tp) && \
            (tp)->t_state == TCPS_ESTABLISHED) {\
                if (ti->ti_flags & TH_PUSH) \
@@ -95,5 +95,5 @@
 #define	TCP_REASS(tp, ti, m, so, flags) { \
 	if ((ti)->ti_seq == (tp)->rcv_nxt && \
-	    (tp)->seg_next == (tcpiphdrp_32)(tp) && \
+	    u32_to_ptr((tp)->seg_next, struct tcpcb *) == (tp) && \
 	    (tp)->t_state == TCPS_ESTABLISHED) { \
 		tp->t_flags |= TF_DELACK; \
@@ -134,6 +134,6 @@
 	 * Find a segment which begins after this one does.
 	 */
-	for (q = (struct tcpiphdr *)tp->seg_next; q != (struct tcpiphdr *)tp;
-	    q = (struct tcpiphdr *)q->ti_next)
+	for (q = u32_to_ptr(tp->seg_next, struct tcpiphdr *); q != (struct tcpiphdr *)tp;
+	    q = u32_to_ptr(q->ti_next, struct tcpiphdr *))
 		if (SEQ_GT(q->ti_seq, ti->ti_seq))
 			break;
@@ -144,7 +144,7 @@
 	 * segment.  If it provides all of our data, drop us.
 	 */
-	if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) {
+	if (u32_to_ptr(q->ti_prev, struct tcpiphdr *) != (struct tcpiphdr *)tp) {
 		register int i;
-		q = (struct tcpiphdr *)q->ti_prev;
+		q = u32_to_ptr(q->ti_prev, struct tcpiphdr *);
 		/* conversion to int (in i) handles seq wraparound */
 		i = q->ti_seq + q->ti_len - ti->ti_seq;
@@ -166,9 +166,9 @@
 			ti->ti_seq += i;
 		}
-		q = (struct tcpiphdr *)(q->ti_next);
+		q = u32_to_ptr(q->ti_next, struct tcpiphdr *);
 	}
 	tcpstat.tcps_rcvoopack++;
 	tcpstat.tcps_rcvoobyte += ti->ti_len;
-	REASS_MBUF(ti) = (mbufp_32) m;		/* XXX */
+	REASS_MBUF_SET(ti, m); /* XXX */
 
 	/*
@@ -183,10 +183,10 @@
 			q->ti_seq += i;
 			q->ti_len -= i;
-			m_adj((struct mbuf *) REASS_MBUF(q), i);
+			m_adj(REASS_MBUF_GET(q), i);
 			break;
 		}
-		q = (struct tcpiphdr *)q->ti_next;
-		m = (struct mbuf *) REASS_MBUF((struct tcpiphdr *)q->ti_prev);
-		remque_32((void *)(q->ti_prev));
+		q = u32_to_ptr(q->ti_next, struct tcpiphdr *);
+		m = REASS_MBUF_GET(u32_to_ptr(q->ti_prev, struct tcpiphdr *));
+		remque_32(u32_to_ptr(q->ti_prev, struct tcpiphdr *));
 		m_freem(m);
 	}
@@ -195,5 +195,5 @@
 	 * Stick new segment in its place.
 	 */
-	insque_32(ti, (void *)(q->ti_prev));
+	insque_32(ti, u32_to_ptr(q->ti_prev, struct tcpiphdr *));
 
 present:
@@ -204,5 +204,5 @@
 	if (!TCPS_HAVEESTABLISHED(tp->t_state))
 		return (0);
-	ti = (struct tcpiphdr *) tp->seg_next;
+	ti = u32_to_ptr(tp->seg_next, struct tcpiphdr *);
 	if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt)
 		return (0);
@@ -213,6 +213,6 @@
 		flags = ti->ti_flags & TH_FIN;
 		remque_32(ti);
-		m = (struct mbuf *) REASS_MBUF(ti); /* XXX */
-		ti = (struct tcpiphdr *)ti->ti_next;
+		m = REASS_MBUF_GET(ti); /* XXX */
+		ti = u32_to_ptr(ti->ti_next, struct tcpiphdr *);
 /*		if (so->so_state & SS_FCANTRCVMORE) */
 		if (so->so_state & SS_FCANTSENDMORE)
@@ -550,5 +550,5 @@
 			}
 		} else if (ti->ti_ack == tp->snd_una &&
-		    tp->seg_next == (tcpiphdrp_32)tp &&
+		    u32_to_ptr(tp->seg_next, struct tcpcb *) == tp &&
 		    ti->ti_len <= sbspace(&so->so_rcv)) {
 			/*
Index: trunk/src/VBox/Devices/Network/slirp/tcp_subr.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/tcp_subr.c	(revision 527)
+++ trunk/src/VBox/Devices/Network/slirp/tcp_subr.c	(revision 530)
@@ -208,5 +208,5 @@
 	
 	memset((char *) tp, 0, sizeof(struct tcpcb));
-	tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp;
+	tp->seg_next = tp->seg_prev = ptr_to_u32((struct tcpiphdr *)tp);
 	tp->t_maxseg = tcp_mssdflt;
 	
@@ -284,9 +284,9 @@
 	
 	/* free the reassembly queue, if any */
-	t = (struct tcpiphdr *) tp->seg_next;
+	t = u32_to_ptr(tp->seg_next, struct tcpiphdr *);
 	while (t != (struct tcpiphdr *)tp) {
-		t = (struct tcpiphdr *)t->ti_next;
-		m = (struct mbuf *) REASS_MBUF((struct tcpiphdr *)t->ti_prev);
-		remque_32((struct tcpiphdr *) t->ti_prev);
+		t = u32_to_ptr(t->ti_next, struct tcpiphdr *);
+		m = REASS_MBUF_GET(u32_to_ptr(t->ti_prev, struct tcpiphdr *));
+		remque_32(u32_to_ptr(t->ti_prev, struct tcpiphdr *));
 		m_freem(m);
 	}
@@ -296,4 +296,5 @@
  */
 /*	free(tp, M_PCB);  */
+	u32ptr_done(ptr_to_u32(ptr), tp);
 	free(tp);
 	so->so_tcpcb = 0;
@@ -1347,2 +1348,136 @@
 	}
 }
+
+#if defined(VBOX) && SIZEOF_CHAR_P != 4
+/** Hash table used for translating pointers to unique uint32_t entries. 
+* The 0 entry is reserved for NULL pointers. */
+void       *g_apvHash[16384];
+/** The number of currently used pointer hash entries. */
+uint32_t    g_cpvHashUsed = 1;
+/** The number of insert collisions. */
+uint32_t    g_cpvHashCollisions = 0;
+/** The number of hash inserts. */
+uint64_t    g_cpvHashInserts = 0;
+/** The number of done calls. */
+uint64_t    g_cpvHashDone = 0;
+
+/**
+ * Slow pointer hashing that deals with automatic inserting and collisions.
+ */
+uint32_t VBoxU32PtrHashSlow(void *pv)
+{
+    uint32_t i;
+    if (pv == NULL)
+        i = 0;
+    else
+    {
+        const uint32_t i1 = ((uintptr_t)pv >> 3) % RT_ELEMENTS(g_apvHash);
+        if (g_apvHash[i1] == pv)
+            i = i1;
+        else
+        {
+            /* 
+             * Try up to 10 times then assume it's an insertion. 
+             * If we didn't find a free entry by then, try another 100 times. 
+             * If that fails, give up.
+             */
+            const uint32_t  i2 = ((uintptr_t)pv >> 2) % 7867;
+            uint32_t        i1stFree = g_apvHash[i1] ? 0 : i1;
+            int             cTries = 10;
+            int             cTries2 = 100;
+
+            i = i1;
+            for (;;)
+            {
+                /* check if we should give in.*/
+                if (--cTries > 0) 
+                {
+                    if (i1stFree != 0)
+                    {
+                        i = i1stFree;
+                        g_apvHash[i] = pv;
+                        g_cpvHashUsed++;
+                        if (i != i1)
+                            g_cpvHashCollisions++;
+                        g_cpvHashInserts++;
+                        break;
+                    }
+                    if (!cTries2)
+                    {
+                        AssertReleaseMsgFailed(("NAT pointer hash error. pv=%p g_cpvHashUsed=%d g_cpvHashCollisions=%u\n", 
+                                                pv, g_cpvHashUsed, g_cpvHashCollisions));
+                        i = 0;
+                        break;
+                    }
+                    cTries = cTries2;
+                    cTries2 = 0;
+                }
+
+                /* advance to the next hash entry and test it. */
+                i = (i + i2) % RT_ELEMENTS(g_apvHash);
+                while (RT_UNLIKELY(!i))
+                    i = (i + i2) % RT_ELEMENTS(g_apvHash);
+                if (g_apvHash[i] == pv)
+                    break;
+                if (RT_UNLIKELY(!i1stFree && !g_apvHash[i]))
+                    i1stFree = i;
+            }
+        }
+    }
+    return i;
+}
+
+
+/**
+ * Removes the pointer from the hash table.
+ */
+void VBoxU32PtrDone(void *pv, uint32_t iHint)
+{
+    /* We don't count NULL pointers. */
+    if (pv == NULL)
+        return;
+    g_cpvHashDone++;
+
+    /* try the hint */
+    if (    iHint
+        &&  iHint < RT_ELEMENTS(g_apvHash)
+        &&  g_apvHash[iHint] == pv)
+    {
+        g_apvHash[iHint] = NULL;
+        g_cpvHashUsed--;
+        return;
+    }
+
+    iHint = ((uintptr_t)pv >> 3) % RT_ELEMENTS(g_apvHash);
+    if (RT_UNLIKELY(g_apvHash[iHint] != pv))
+    {
+        /* 
+         * Try up to 120 times then assert.
+         */
+        const uint32_t  i2 = ((uintptr_t)pv >> 2) % 7867;
+        int             cTries = 120;
+        for (;;)
+        {
+            /* advance to the next hash entry and test it. */
+            iHint = (iHint + i2) % RT_ELEMENTS(g_apvHash);
+            while (RT_UNLIKELY(!iHint))
+                iHint = (iHint + i2) % RT_ELEMENTS(g_apvHash);
+            if (g_apvHash[iHint] == pv)
+                break;
+
+            /* check if we should give in.*/
+            if (--cTries > 0)
+            {
+                AssertReleaseMsgFailed(("NAT pointer hash error. pv=%p g_cpvHashUsed=%u g_cpvHashCollisions=%u\n", 
+                                        pv, g_cpvHashUsed, g_cpvHashCollisions));
+                return;
+            }
+        }
+    }
+
+    /* found it */
+    g_apvHash[iHint] = NULL;
+    g_cpvHashUsed--;
+}
+
+#endif 
Index: trunk/src/VBox/Devices/Network/slirp/tcp_var.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/tcp_var.h	(revision 527)
+++ trunk/src/VBox/Devices/Network/slirp/tcp_var.h	(revision 530)
@@ -43,6 +43,47 @@
 #if SIZEOF_CHAR_P == 4
  typedef struct tcpiphdr *tcpiphdrp_32;
+  /* VBox change that's to much bother to #ifdef. */
+# define u32ptr_done(u32, ptr)  do {} while (0)
+# define ptr_to_u32(ptr)        (ptr)
+# define u32_to_ptr(u32, type)  ((type)(u32))
 #else
  typedef u_int32_t tcpiphdrp_32;
+# ifdef VBOX
+#  include <iprt/types.h> 
+#  include <iprt/assert.h>
+
+   /* VBox change that's to much bother to #ifdef. */
+#  define u32ptr_done(u32, ptr) VBoxU32PtrDone((ptr), (u32))    
+#  define ptr_to_u32(ptr)       VBoxU32PtrHash((ptr))
+#  define u32_to_ptr(u32, type) ((type)VBoxU32PtrLookup(u32))
+
+    extern void       *g_apvHash[16384];
+
+    extern void     VBoxU32PtrDone(void *pv, uint32_t iHint);
+    extern uint32_t VBoxU32PtrHashSlow(void *pv);
+    
+    /** Hash the pointer, inserting it if need be. */
+    DECLINLINE(uint32_t) VBoxU32PtrHash(void *pv)
+    {
+        uint32_t i = ((uintptr_t)pv >> 3) % RT_ELEMENTS(g_apvHash);
+        if (RT_LIKELY(g_apvHash[i] == pv && pv))
+            return i;
+        return VBoxU32PtrHashSlow(pv);
+    }
+    /** Lookup the hash value. */
+    DECLINLINE(void *) VBoxU32PtrLookup(uint32_t i)
+    {
+        void *pv;
+        Assert(i < RT_ELEMENTS(g_apvHash));
+        pv = g_apvHash[i];
+        Assert(pv || !i); 
+        return pv;
+    }
+# else /* !VBOX */
+   /* VBox change that's to much bother to #ifdef. */
+#  define u32ptr_done(u32, ptr)   do {} while (0)
+#  define ptr_to_u32(ptr)         (ptr)
+#  define u32_to_ptr(u32, type)   ((type)(u32))
+# endif /* !VBOX */
 #endif
 
@@ -181,8 +222,14 @@
 #if SIZEOF_CHAR_P == 4
 typedef struct mbuf *mbufp_32;
+/* VBox change which is too much bother to #ifdef */
+# define REASS_MBUF_SET(ti, p) (*(mbufp_32 *)&((ti)->ti_t)) = (p)
+# define REASS_MBUF_GET(ti)    ((struct mbuf *)(*(mbufp_32 *)&((ti)->ti_t)))
 #else
 typedef u_int32_t mbufp_32;
+/* VBox change which is too much bother to #ifdef */
+# define REASS_MBUF_SET(ti, p) (*(mbufp_32 *)&((ti)->ti_t)) = ptr_to_u32(p)
+# define REASS_MBUF_GET(ti)    u32_to_ptr((*(mbufp_32 *)&((ti)->ti_t)), struct mbuf *)
 #endif
-#define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t))
+/*#define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t)) - replaced by REASS_MBUF_GET/SET */
 
 /*
