summaryrefslogtreecommitdiff
path: root/emulators/virtualbox
diff options
context:
space:
mode:
Diffstat (limited to 'emulators/virtualbox')
-rw-r--r--emulators/virtualbox/Makefile13
-rw-r--r--emulators/virtualbox/files/patch-src-VBox-HostDrivers-VBoxNetFlt-VBoxNetFltInternal.h28
-rw-r--r--emulators/virtualbox/files/patch-src-VBox-HostDrivers-VBoxNetFlt-freebsd-VBoxNetFlt-freebsd.c375
-rw-r--r--emulators/virtualbox/files/patch-src-VBox-apps-adpctl_VBoxNetAdpCtl.cpp207
-rw-r--r--emulators/virtualbox/pkg-plist2
5 files changed, 621 insertions, 4 deletions
diff --git a/emulators/virtualbox/Makefile b/emulators/virtualbox/Makefile
index 3538d0054d94..3d821daa23a0 100644
--- a/emulators/virtualbox/Makefile
+++ b/emulators/virtualbox/Makefile
@@ -7,6 +7,7 @@
PORTNAME= virtualbox
DISTVERSION= 3.0.51r22902
+PORTREVISION= 2
CATEGORIES= emulators kld
MASTER_SITES= http://tmp.chruetertee.ch/ \
http://freebsd.unixfreunde.de/sources/ \
@@ -142,15 +143,21 @@ BROKEN= Does not compile on FreeBSD 6.X
KMK_ARCH= freebsd.x86
PLIST_SUB+= I386=""
.else
-.if !exists(/usr/lib32)
-IGNORE= requires 32-bit libraries installed under /usr/lib32
-.endif
KMK_ARCH= freebsd.${ARCH}
PLIST_SUB+= I386="@comment "
.endif
.include <bsd.port.pre.mk>
+pre-everything::
+.if ${ARCH} == "amd64"
+.if !exists(/usr/lib32)
+ @${ECHO} 'Requires 32-bit libraries installed under /usr/lib32.'
+ @${ECHO} 'Do: cd /usr/src; make build32 install32; ldconfig -v -m -R /usr/lib32'
+ @${FALSE}
+.endif
+.endif
+
post-patch:
@${ECHO} 'VBOX_PATH_APP_PRIVATE_ARCH = ${PREFIX}/lib/virtualbox' > ${WRKSRC}/LocalConfig.kmk
@${ECHO} 'VBOX_PATH_SHARED_LIBS = ${PREFIX}/lib/virtualbox' >> ${WRKSRC}/LocalConfig.kmk
diff --git a/emulators/virtualbox/files/patch-src-VBox-HostDrivers-VBoxNetFlt-VBoxNetFltInternal.h b/emulators/virtualbox/files/patch-src-VBox-HostDrivers-VBoxNetFlt-VBoxNetFltInternal.h
new file mode 100644
index 000000000000..250a1960a7f4
--- /dev/null
+++ b/emulators/virtualbox/files/patch-src-VBox-HostDrivers-VBoxNetFlt-VBoxNetFltInternal.h
@@ -0,0 +1,28 @@
+Index: src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h
+===================================================================
+--- src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h (revision 23391)
++++ src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h (working copy)
+@@ -206,6 +206,14 @@
+ hook_p output;
+ /** Original interface flags */
+ unsigned int flags;
++ /** Input queue */
++ struct ifqueue inq;
++ /** Output queue */
++ struct ifqueue outq;
++ /** Input task */
++ struct task tskin;
++ /** Output task */
++ struct task tskout;
+ /** The MAC address of the interface. */
+ RTMAC Mac;
+ /** @} */
+@@ -241,6 +249,8 @@
+ # endif
+ #elif defined(RT_OS_LINUX)
+ uint8_t abPadding[320];
++#elif defined(RT_OS_FREEBSD)
++ uint8_t abPadding[320];
+ #else
+ uint8_t abPadding[128];
+ #endif
diff --git a/emulators/virtualbox/files/patch-src-VBox-HostDrivers-VBoxNetFlt-freebsd-VBoxNetFlt-freebsd.c b/emulators/virtualbox/files/patch-src-VBox-HostDrivers-VBoxNetFlt-freebsd-VBoxNetFlt-freebsd.c
new file mode 100644
index 000000000000..bc23fb14a545
--- /dev/null
+++ b/emulators/virtualbox/files/patch-src-VBox-HostDrivers-VBoxNetFlt-freebsd-VBoxNetFlt-freebsd.c
@@ -0,0 +1,375 @@
+Index: src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c
+===================================================================
+--- src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c (revision 23391)
++++ src/VBox/HostDrivers/VBoxNetFlt/freebsd/VBoxNetFlt-freebsd.c (working copy)
+@@ -43,6 +43,8 @@
+ #include <sys/socket.h>
+ #include <sys/sockio.h>
+ #include <sys/syscallsubr.h>
++#include <sys/queue.h>
++#include <sys/taskqueue.h>
+
+ #include <net/if.h>
+ #include <net/if_var.h>
+@@ -78,8 +80,6 @@
+ static ng_rcvdata_t ng_vboxnetflt_rcvdata;
+ static ng_disconnect_t ng_vboxnetflt_disconnect;
+ static int ng_vboxnetflt_mod_event(module_t mod, int event, void *data);
+-static int ng_vboxnetflt_rcv_in(hook_p node, item_p item);
+-static int ng_vboxnetflt_rcv_out(hook_p node, item_p item);
+
+ /** Netgraph node type */
+ #define NG_VBOXNETFLT_NODE_TYPE "vboxnetflt"
+@@ -112,8 +112,8 @@
+ {
+ .version = NG_ABI_VERSION,
+ .name = NG_VBOXNETFLT_NODE_TYPE,
+- .mod_event = vboxnetflt_modevent,
+- .constructor = ng_vboxnetflt_constructor,
++ .mod_event = vboxnetflt_modevent,
++ .constructor = ng_vboxnetflt_constructor,
+ .rcvmsg = ng_vboxnetflt_rcvmsg,
+ .shutdown = ng_vboxnetflt_shutdown,
+ .newhook = ng_vboxnetflt_newhook,
+@@ -267,16 +267,12 @@
+ if (strcmp(name, NG_VBOXNETFLT_HOOK_IN) == 0)
+ {
+ #if __FreeBSD_version >= 800000
+- NG_HOOK_SET_RCVDATA(hook, ng_vboxnetflt_rcv_in);
+ NG_HOOK_SET_TO_INBOUND(hook);
+ #endif
+ pThis->u.s.input = hook;
+ }
+ else if (strcmp(name, NG_VBOXNETFLT_HOOK_OUT) == 0)
+ {
+-#if __FreeBSD_version >= 800000
+- NG_HOOK_SET_RCVDATA(hook, ng_vboxnetflt_rcv_out);
+-#endif
+ pThis->u.s.output = hook;
+ }
+ else
+@@ -310,161 +306,171 @@
+
+ /**
+ * Handle data on netgraph hooks.
++ * Frames processing is deferred to a taskqueue because this might
++ * be called with non-sleepable locks held and code paths inside
++ * the virtual switch might sleep.
+ */
+ static int ng_vboxnetflt_rcvdata(hook_p hook, item_p item)
+ {
+ const node_p node = NG_HOOK_NODE(hook);
+ PVBOXNETFLTINS pThis = NG_NODE_PRIVATE(node);
++ struct ifnet *ifp = pThis->u.s.ifp;
+ struct mbuf *m;
++ struct m_tag *mtag;
++ bool fActive;
+
++ fActive = ASMAtomicUoReadBool(&pThis->fActive);
++
++ NGI_GET_M(item, m);
++ NG_FREE_ITEM(item);
++
++ /* Locate tag to see if processing should be skipped for this frame */
++ mtag = m_tag_locate(m, MTAG_VBOX, PACKET_TAG_VBOX, NULL);
++ if (mtag != NULL)
++ {
++ m_tag_unlink(m, mtag);
++ m_tag_free(mtag);
++ }
++
++ /*
++ * Handle incoming hook. This is connected to the
++ * input path of the interface, thus handling incoming frames.
++ */
+ if (pThis->u.s.input == hook)
+- return ng_vboxnetflt_rcv_in(hook, item);
++ {
++ if (mtag != NULL || !fActive)
++ {
++ ether_demux(ifp, m);
++ return (0);
++ }
++ mtx_lock_spin(&pThis->u.s.inq.ifq_mtx);
++ _IF_ENQUEUE(&pThis->u.s.inq, m);
++ mtx_unlock_spin(&pThis->u.s.inq.ifq_mtx);
++ taskqueue_enqueue_fast(taskqueue_fast, &pThis->u.s.tskin);
++ }
++ /**
++ * Handle mbufs on the outgoing hook, frames going to the interface
++ */
+ else if (pThis->u.s.output == hook)
+- return ng_vboxnetflt_rcv_out(hook, item);
++ {
++ if (mtag != NULL || !fActive)
++ return ether_output_frame(ifp, m);
++ mtx_lock_spin(&pThis->u.s.outq.ifq_mtx);
++ _IF_ENQUEUE(&pThis->u.s.outq, m);
++ mtx_unlock_spin(&pThis->u.s.outq.ifq_mtx);
++ taskqueue_enqueue_fast(taskqueue_fast, &pThis->u.s.tskout);
++ }
+ else
+ {
+- NGI_GET_M(item, m);
+- NG_FREE_ITEM(item);
++ m_freem(m);
+ }
+ return (0);
+ }
+
++static int ng_vboxnetflt_shutdown(node_p node)
++{
++ PVBOXNETFLTINS pThis = NG_NODE_PRIVATE(node);
++ bool fActive;
++
++ /* Prevent node shutdown if we're active */
++ fActive = ASMAtomicUoReadBool(&pThis->fActive);
++ if (fActive)
++ return (EBUSY);
++ NG_NODE_UNREF(node);
++ return (0);
++}
++
++static int ng_vboxnetflt_disconnect(hook_p hook)
++{
++ return (0);
++}
++
+ /**
+- * Handle incoming hook. This is connected to the
+- * input path of the interface, thus handling incoming frames.
++ * Input processing task, handles incoming frames
+ */
+-static int ng_vboxnetflt_rcv_in(hook_p hook, item_p item)
++static void vboxNetFltFreeBSDinput(void *arg, int pending)
+ {
++ PVBOXNETFLTINS pThis = (PVBOXNETFLTINS)arg;
+ struct mbuf *m, *m0;
+- struct m_tag *mtag;
+- const node_p node = NG_HOOK_NODE(hook);
+- PVBOXNETFLTINS pThis = NG_NODE_PRIVATE(node);
+ struct ifnet *ifp = pThis->u.s.ifp;
+- bool fActive, fDropIt = false;
+ unsigned int cSegs = 0;
++ bool fDropIt = false, fActive;
+ PINTNETSG pSG;
+
+- NGI_GET_M(item, m);
+- NG_FREE_ITEM(item);
+-
+- fActive = ASMAtomicUoReadBool(&pThis->fActive);
+- if (!fActive)
+- goto out;
+-
+- mtag = m_tag_locate(m, MTAG_VBOX, PACKET_TAG_VBOX, NULL);
+- if (mtag != NULL)
+- {
+- m_tag_unlink(m, mtag);
+- m_tag_free(mtag);
+- goto out;
+- }
+ vboxNetFltRetain(pThis, true /* fBusy */);
+-
+- for (m0 = m; m0 != NULL; m0 = m0->m_next)
++ for (;;)
+ {
+- if (m0->m_len > 0)
+- cSegs++;
+- }
++ mtx_lock_spin(&pThis->u.s.inq.ifq_mtx);
++ _IF_DEQUEUE(&pThis->u.s.inq, m);
++ mtx_unlock_spin(&pThis->u.s.inq.ifq_mtx);
++ if (m == NULL)
++ break;
+
++ for (m0 = m; m0 != NULL; m0 = m0->m_next)
++ if (m0->m_len > 0)
++ cSegs++;
++
+ #ifdef PADD_RUNT_FRAMES_FROM_HOST
+- if (m_length(m, NULL) < 60)
+- cSegs++;
++ if (m_length(m, NULL) < 60)
++ cSegs++;
+ #endif
+
+- /* Create a copy of the mbuf and hand it to the virtual switch */
+- pSG = RTMemTmpAlloc(RT_OFFSETOF(INTNETSG, aSegs[cSegs]));
+- vboxNetFltFreeBSDMBufToSG(pThis, m, pSG, cSegs, 0);
+- fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, INTNETTRUNKDIR_WIRE);
+- RTMemTmpFree(pSG);
++ /* Create a copy and deliver to the virtual switch */
++ pSG = RTMemTmpAlloc(RT_OFFSETOF(INTNETSG, aSegs[cSegs]));
++ vboxNetFltFreeBSDMBufToSG(pThis, m, pSG, cSegs, 0);
++ fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, INTNETTRUNKDIR_HOST);
++ RTMemTmpFree(pSG);
++ if (fDropIt)
++ m_freem(m);
++ else
++ ether_demux(ifp, m);
++ }
+ vboxNetFltRelease(pThis, true /* fBusy */);
+-
+-out:
+- /* Only deliver it to the host stack if the destination weren't a guest */
+- if (fDropIt)
+- {
+- m_freem(m);
+- return (0);
+- }
+- ether_demux(ifp, m);
+- return (0);
+ }
+
+ /**
+- * Handle mbufs on the outgoing hook, frames going to the interface
++ * Output processing task, handles outgoing frames
+ */
+-static int ng_vboxnetflt_rcv_out(hook_p hook, item_p item)
++static void vboxNetFltFreeBSDoutput(void *arg, int pending)
+ {
++ PVBOXNETFLTINS pThis = (PVBOXNETFLTINS)arg;
+ struct mbuf *m, *m0;
+- struct m_tag *mtag;
+- const node_p node = NG_HOOK_NODE(hook);
+- PVBOXNETFLTINS pThis = NG_NODE_PRIVATE(node);
+ struct ifnet *ifp = pThis->u.s.ifp;
+ unsigned int cSegs = 0;
+ bool fDropIt = false, fActive;
+ PINTNETSG pSG;
+
+- NGI_GET_M(item, m);
+- NG_FREE_ITEM(item);
+-
+- fActive = ASMAtomicUoReadBool(&pThis->fActive);
+- if (!fActive)
+- return ether_output_frame(ifp, m);
+-
+ vboxNetFltRetain(pThis, true /* fBusy */);
+- /* Pass directly to interface if the packet originated from us */
+- mtag = m_tag_locate(m, MTAG_VBOX, PACKET_TAG_VBOX, NULL);
+- if (mtag != NULL)
++ for (;;)
+ {
+- m_tag_unlink(m, mtag);
+- m_tag_free(mtag);
+- goto out;
+- }
++ mtx_lock_spin(&pThis->u.s.outq.ifq_mtx);
++ _IF_DEQUEUE(&pThis->u.s.outq, m);
++ mtx_unlock_spin(&pThis->u.s.outq.ifq_mtx);
++ if (m == NULL)
++ break;
+
+- for (m0 = m; m0 != NULL; m0 = m0->m_next)
+- {
+- if (m0->m_len > 0)
+- cSegs++;
+- }
++ for (m0 = m; m0 != NULL; m0 = m0->m_next)
++ if (m0->m_len > 0)
++ cSegs++;
+
+ #ifdef PADD_RUNT_FRAMES_FROM_HOST
+- if (m_length(m, NULL) < 60)
+- cSegs++;
++ if (m_length(m, NULL) < 60)
++ cSegs++;
+ #endif
+- /* Create a copy and deliver to the virtual switch */
+- pSG = RTMemTmpAlloc(RT_OFFSETOF(INTNETSG, aSegs[cSegs]));
+- vboxNetFltFreeBSDMBufToSG(pThis, m, pSG, cSegs, 0);
+- fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, INTNETTRUNKDIR_HOST);
+- RTMemTmpFree(pSG);
++ /* Create a copy and deliver to the virtual switch */
++ pSG = RTMemTmpAlloc(RT_OFFSETOF(INTNETSG, aSegs[cSegs]));
++ vboxNetFltFreeBSDMBufToSG(pThis, m, pSG, cSegs, 0);
++ fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, INTNETTRUNKDIR_HOST);
++ RTMemTmpFree(pSG);
+
+-out:
++ if (fDropIt)
++ m_freem(m);
++ else
++ ether_output_frame(ifp, m);
++ }
+ vboxNetFltRelease(pThis, true /* fBusy */);
+- if (fDropIt)
+- {
+- m_freem(m);
+- return (0);
+- }
+-
+- return ether_output_frame(ifp, m);
+ }
+
+-static int ng_vboxnetflt_shutdown(node_p node)
+-{
+- PVBOXNETFLTINS pThis = NG_NODE_PRIVATE(node);
+- bool fActive;
+-
+- /* Prevent node shutdown if we're active */
+- fActive = ASMAtomicUoReadBool(&pThis->fActive);
+- if (fActive)
+- return (EBUSY);
+- NG_NODE_UNREF(node);
+- return (0);
+-}
+-
+-static int ng_vboxnetflt_disconnect(hook_p hook)
+-{
+- return (0);
+-}
+-
+ /**
+ * Called to deliver a frame to either the host, the wire or both.
+ */
+@@ -536,13 +542,23 @@
+
+ /* Create a new netgraph node for this instance */
+ if (ng_make_node_common(&ng_vboxnetflt_typestruct, &node) != 0)
+- return VERR_INTERNAL_ERROR;
++ return VERR_INTERNAL_ERROR;
+
+ RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
+ ASMAtomicUoWritePtr((void * volatile *)&pThis->u.s.ifp, ifp);
+ pThis->u.s.node = node;
+ bcopy(IF_LLADDR(ifp), &pThis->u.s.Mac, ETHER_ADDR_LEN);
+ ASMAtomicUoWriteBool(&pThis->fDisconnectedFromHost, false);
++ /* Initialize deferred input queue */
++ bzero(&pThis->u.s.inq, sizeof(struct ifqueue));
++ mtx_init(&pThis->u.s.inq.ifq_mtx, "vboxnetflt inq", NULL, MTX_SPIN);
++ TASK_INIT(&pThis->u.s.tskin, 0, vboxNetFltFreeBSDinput, pThis);
++
++ /* Initialize deferred output queue */
++ bzero(&pThis->u.s.outq, sizeof(struct ifqueue));
++ mtx_init(&pThis->u.s.outq.ifq_mtx, "vboxnetflt outq", NULL, MTX_SPIN);
++ TASK_INIT(&pThis->u.s.tskout, 0, vboxNetFltFreeBSDoutput, pThis);
++
+ RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+
+ NG_NODE_SET_PRIVATE(node, pThis);
+@@ -571,7 +587,10 @@
+ }
+
+ if (ifp0 != NULL)
++ {
++ vboxNetFltOsDeleteInstance(pThis);
+ vboxNetFltOsInitInstance(pThis, NULL);
++ }
+
+ return !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost);
+ }
+@@ -579,6 +598,12 @@
+ void vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis)
+ {
+
++ taskqueue_drain(taskqueue_fast, &pThis->u.s.tskin);
++ taskqueue_drain(taskqueue_fast, &pThis->u.s.tskout);
++
++ mtx_destroy(&pThis->u.s.inq.ifq_mtx);
++ mtx_destroy(&pThis->u.s.outq.ifq_mtx);
++
+ if (pThis->u.s.node != NULL)
+ ng_rmnode_self(pThis->u.s.node);
+ pThis->u.s.node = NULL;
diff --git a/emulators/virtualbox/files/patch-src-VBox-apps-adpctl_VBoxNetAdpCtl.cpp b/emulators/virtualbox/files/patch-src-VBox-apps-adpctl_VBoxNetAdpCtl.cpp
new file mode 100644
index 000000000000..955bf7a3a151
--- /dev/null
+++ b/emulators/virtualbox/files/patch-src-VBox-apps-adpctl_VBoxNetAdpCtl.cpp
@@ -0,0 +1,207 @@
+--- src/apps/adpctl/VBoxNetAdpCtl.cpp.r22902 2009-04-10 14:03:59.000000000 +0200
++++ src/apps/adpctl/VBoxNetAdpCtl.cpp 2009-09-16 14:07:11.000000000 +0200
+@@ -1,4 +1,4 @@
+-/* $Id: VBoxNetAdpCtl.cpp 18864 2009-04-10 12:03:59Z vboxsync $ */
++/* $Id: VBoxNetAdpCtl.cpp 23064 2009-09-16 12:07:11Z vboxsync $ */
+ /** @file
+ * Apps - VBoxAdpCtl, Configuration tool for vboxnetX adapters.
+ */
+@@ -24,7 +24,6 @@
+ /*******************************************************************************
+ * Header Files *
+ *******************************************************************************/
+-#include <assert.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -36,11 +35,12 @@
+ # include <sys/ioccom.h>
+ #endif
+
+-/* @todo Error codes must be moved to some header file */
+-#define ADPCTLERR_NO_CTL_DEV 3
+-#define ADPCTLERR_IOCTL_FAILED 4
++/** @todo Error codes must be moved to some header file */
++#define ADPCTLERR_BAD_NAME 2
++#define ADPCTLERR_NO_CTL_DEV 3
++#define ADPCTLERR_IOCTL_FAILED 4
+
+-/* @todo These are duplicates from src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h */
++/** @todo These are duplicates from src/VBox/HostDrivers/VBoxNetAdp/VBoxNetAdpInternal.h */
+ #define VBOXNETADP_CTL_DEV_NAME "/dev/vboxnetctl"
+ #define VBOXNETADP_NAME "vboxnet"
+ #define VBOXNETADP_MAX_NAME_LEN 32
+@@ -85,6 +85,7 @@
+ pcszArg5, /* [network mask] */
+ NULL /* terminator */
+ };
++ char * const envp[] = { (char*)"LC_ALL=C", NULL };
+ int rc = EXIT_SUCCESS;
+ pid_t childPid = fork();
+ switch (childPid)
+@@ -94,7 +95,7 @@
+ rc = EXIT_FAILURE;
+ break;
+ case 0: /* Child process. */
+- if (execv(VBOXADPCTL_IFCONFIG_PATH, (char * const*)argv) == -1)
++ if (execve(VBOXADPCTL_IFCONFIG_PATH, (char * const*)argv, envp) == -1)
+ rc = EXIT_FAILURE;
+ break;
+ default: /* Parent process. */
+@@ -108,15 +109,39 @@
+ #define MAX_ADDRESSES 128
+ #define MAX_ADDRLEN 64
+
+-static bool removeAddresses(const char *pszAdapterName)
++static bool removeAddresses(char *pszAdapterName)
+ {
+- char szCmd[1024], szBuf[1024];
++ char szBuf[1024];
+ char aszAddresses[MAX_ADDRESSES][MAX_ADDRLEN];
++ int rc;
++ int fds[2];
++ char * const argv[] = { VBOXADPCTL_IFCONFIG_PATH, pszAdapterName, NULL };
++ char * const envp[] = { (char*)"LC_ALL=C", NULL };
+
+ memset(aszAddresses, 0, sizeof(aszAddresses));
+- snprintf(szCmd, sizeof(szCmd), VBOXADPCTL_IFCONFIG_PATH " %s", pszAdapterName);
+- FILE *fp = popen(szCmd, "r");
+
++ rc = pipe(fds);
++ if (rc < 0)
++ return false;
++
++ pid_t pid = fork();
++ if (pid < 0)
++ return false;
++
++ if (pid == 0)
++ {
++ /* child */
++ close(fds[0]);
++ close(STDOUT_FILENO);
++ rc = dup2(fds[1], STDOUT_FILENO);
++ if (rc >= 0)
++ execve(VBOXADPCTL_IFCONFIG_PATH, argv, envp);
++ return false;
++ }
++
++ /* parent */
++ close(fds[1]);
++ FILE *fp = fdopen(fds[0], "r");
+ if (!fp)
+ return false;
+
+@@ -124,9 +149,6 @@
+ for (cAddrs = 0; cAddrs < MAX_ADDRESSES && fgets(szBuf, sizeof(szBuf), fp);)
+ {
+ int cbSkipWS = strspn(szBuf, " \t");
+-#if 0 /* Don't use this! assert() breaks the mac build. Use IPRT or be a rectangular building thing. */
+- assert(cbSkipWS < 20);
+-#endif
+ char *pszWord = strtok(szBuf + cbSkipWS, " ");
+ /* We are concerned with IPv6 address lines only. */
+ if (!pszWord || strcmp(pszWord, "inet6"))
+@@ -143,11 +165,12 @@
+ continue;
+ strncpy(aszAddresses[cAddrs++], pszWord, MAX_ADDRLEN-1);
+ }
+- pclose(fp);
++ fclose(fp);
+
+ for (int i = 0; i < cAddrs; i++)
+ {
+- if (executeIfconfig(pszAdapterName, "inet6", VBOXADPCTL_DEL_CMD, aszAddresses[i]) != EXIT_SUCCESS)
++ if (executeIfconfig(pszAdapterName, "inet6",
++ VBOXADPCTL_DEL_CMD, aszAddresses[i]) != EXIT_SUCCESS)
+ return false;
+ }
+
+@@ -166,19 +189,41 @@
+ int rc = ioctl(fd, uCmd, pData);
+ if (rc == -1)
+ {
+- perror("VBoxNetAdpCtl: ioctl failed for " VBOXNETADP_CTL_DEV_NAME);
++ perror("VBoxNetAdpCtl: ioctl failed for " VBOXNETADP_CTL_DEV_NAME);
+ rc = ADPCTLERR_IOCTL_FAILED;
+ }
+-
++
+ close(fd);
+-
++
+ return rc;
+ }
+
++int checkAdapterName(const char *pcszNameIn, char *pszNameOut)
++{
++ int iAdapterIndex = -1;
++
++ if ( strlen(pcszNameIn) >= VBOXNETADP_MAX_NAME_LEN
++ || sscanf(pcszNameIn, "vboxnet%d", &iAdapterIndex) != 1
++ || iAdapterIndex < 0 || iAdapterIndex > 99 )
++ {
++ fprintf(stderr, "Setting configuration for %s is not supported.\n", pcszNameIn);
++ return ADPCTLERR_BAD_NAME;
++ }
++ sprintf(pszNameOut, "vboxnet%d", iAdapterIndex);
++ if (strcmp(pszNameOut, pcszNameIn))
++ {
++ fprintf(stderr, "Invalid adapter name %s.\n", pcszNameIn);
++ return ADPCTLERR_BAD_NAME;
++ }
++
++ return 0;
++}
++
+ int main(int argc, char *argv[])
+
+ {
+- const char *pszAdapterName;
++ char szAdapterName[VBOXNETADP_MAX_NAME_LEN];
++ char *pszAdapterName;
+ const char *pszAddress;
+ const char *pszNetworkMask = NULL;
+ const char *pszOption = NULL;
+@@ -216,13 +261,18 @@
+ pszAddress = argv[2];
+ if (strcmp("remove", pszAddress) == 0)
+ {
+- strncpy(Req.szName, pszAdapterName, sizeof(Req.szName));
++ rc = checkAdapterName(pszAdapterName, szAdapterName);
++ if (rc)
++ return rc;
++ memset(&Req, '\0', sizeof(Req));
++ snprintf(Req.szName, sizeof(Req.szName), "%s", szAdapterName);
+ return doIOCtl(VBOXNETADP_CTL_REMOVE, &Req);
+ }
+ break;
+ case 2:
+ if (strcmp("add", argv[1]) == 0)
+ {
++ memset(&Req, '\0', sizeof(Req));
+ rc = doIOCtl(VBOXNETADP_CTL_ADD, &Req);
+ if (rc == 0)
+ puts(Req.szName);
+@@ -237,11 +287,11 @@
+ return 1;
+ }
+
+- if (strncmp("vboxnet", pszAdapterName, 7))
+- {
+- fprintf(stderr, "Setting configuration for %s is not supported.\n", pszAdapterName);
+- return 2;
+- }
++ rc = checkAdapterName(pszAdapterName, szAdapterName);
++ if (rc)
++ return rc;
++
++ pszAdapterName = szAdapterName;
+
+ if (fRemove)
+ {
+@@ -276,3 +326,4 @@
+ }
+ return rc;
+ }
++
diff --git a/emulators/virtualbox/pkg-plist b/emulators/virtualbox/pkg-plist
index 701bcf61f230..bdafc64fb6ee 100644
--- a/emulators/virtualbox/pkg-plist
+++ b/emulators/virtualbox/pkg-plist
@@ -592,7 +592,7 @@ include/virtualbox/xpcom/xpcom-config.h
%%QT4%%@dirrmtry share/icons
%%QT4%%@dirrmtry share/applications
@dirrm lib/virtualbox/components
-@dirrm lib/virtualbox/additions
+%%GUESTADDITIONS%%@dirrm lib/virtualbox/additions
@dirrm lib/virtualbox
@cwd /
%%KMODDIR%%/vboxdrv.ko