VBoxNetAdp-darwin.cpp revision e86538a7bc028e823f16f8982e90f0c7ef5d4ece
/* $Id$ */
/** @file
* VBoxNetAdp - Virtual Network Adapter Driver (Host), Darwin Specific Code.
*/
/*
* Copyright (C) 2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
/*
* Deal with conflicts first.
* PVM - BSD mess, that FreeBSD has correct a long time ago.
*/
#define LOG_GROUP LOG_GROUP_NET_ADP_DRV
#include <iprt/initterm.h>
#include <iprt/semaphore.h>
#include <iprt/spinlock.h>
RT_C_DECLS_BEGIN /* Buggy 10.4 headers, fixed in 10.5. */
#include <sys/kpi_mbuf.h>
#include <net/ethernet.h>
#include <net/if_ether.h>
#include <net/if_types.h>
#define VBOXNETADP_OS_SPECFIC 1
#include "../VBoxNetAdpInternal.h"
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
/** The maximum number of SG segments.
* Used to prevent stack overflow and similar bad stuff. */
#define VBOXNETADP_DARWIN_MAX_SEGS 32
#define VBOXNETADP_DARWIN_MAX_FAMILIES 4
#define VBOXNETADP_DARWIN_NAME "vboxnet"
#define VBOXNETADP_DARWIN_MTU 1500
#define VBOXNETADP_DARWIN_DETACH_TIMEOUT 500
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
static int VBoxNetAdpDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess);
/*******************************************************************************
* Global Variables *
*******************************************************************************/
/**
* Declare the module stuff.
*/
/**
* The (common) global data.
*/
static void *g_hCtlDev = 0; /* FS dev handle */
/**
* The character device switch table for the driver.
*/
{
/*.d_open = */VBoxNetAdpDarwinOpen,
/*.d_close = */VBoxNetAdpDarwinClose,
/*.d_read = */eno_rdwrt,
/*.d_write = */eno_rdwrt,
/*.d_ioctl = */VBoxNetAdpDarwinIOCtl,
/*.d_stop = */eno_stop,
/*.d_reset = */eno_reset,
/*.d_ttys = */NULL,
/*.d_select = */eno_select,
/*.d_mmap = */eno_mmap,
/*.d_strategy = */eno_strat,
/*.d_getc = */eno_getc,
/*.d_putc = */eno_putc,
/*.d_type = */0
};
{
/* Generate UUID from name and MAC address. */
}
{
return 0;
}
{
u_int32_t i;
for (i = 0; i < VBOXNETADP_MAX_FAMILIES; i++)
if (pThis->u.s.aAttachedFamilies[i] == 0)
{
break;
}
}
{
u_int32_t i;
for (i = 0; i < VBOXNETADP_MAX_FAMILIES; i++)
pThis->u.s.aAttachedFamilies[i] = 0;
}
static errno_t vboxNetAdpDarwinAddProto(ifnet_t pIface, protocol_family_t Family, const struct ifnet_demux_desc *pDemuxDesc, u_int32_t nDesc)
{
}
{
}
{
Log2(("vboxNetAdpDarwinDetach: Signaling detach to vboxNetAdpUnregisterDevice.\n"));
/* Let vboxNetAdpDarwinUnregisterDevice know that the interface has been detached. */
}
{
int rc;
struct ifnet_init_params Params;
struct sockaddr_dl mac;
if (RT_FAILURE(rc))
{
return rc;
}
if (!err)
{
if (!err)
{
err = ifnet_set_flags(pThis->u.s.pIface, IFF_RUNNING | IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST, 0xFFFF);
if (!err)
{
return VINF_SUCCESS;
}
else
}
else
}
else
return RTErrConvertFromErrno(err);
}
{
u_int32_t i;
/* Bring down the interface */
int rc = VINF_SUCCESS;
if (err)
Log(("vboxNetAdpDarwinUnregisterDevice: Failed to bring down interface "
"(err=%d).\n", err));
/* Detach all protocols. */
for (i = 0; i < VBOXNETADP_MAX_FAMILIES; i++)
if (pThis->u.s.aAttachedFamilies[i])
if (err)
Log(("vboxNetAdpDarwinUnregisterDevice: Failed to detach interface "
"(err=%d).\n", err));
Log2(("vboxNetAdpDarwinUnregisterDevice: Waiting for 'detached' event...\n"));
/* Wait until we get a signal from detach callback. */
if (rc == VERR_TIMEOUT)
LogRel(("VBoxAdpDrv: Failed to detach interface %s%d\n.",
if (err)
}
/**
* Device open. Called on open /dev/vboxnetctl
*
* @param pInode Pointer to inode info structure.
* @param pFilp Associated file pointer.
*/
{
char szName[128];
szName[0] = '\0';
return 0;
}
/**
* Close device.
*/
{
return 0;
}
/**
* Device I/O Control entry point.
*
* @returns Darwin for slow IOCtls and VBox status code for the fast ones.
* @param Dev The device number (major+minor).
* @param iCmd The IOCtl command.
* @param pData Pointer to the data (if any it's a SUPDRVIOCTLDATA (kernel copy)).
* @param fFlags Flag saying we're a character device (like we didn't know already).
* @param pProcess The process issuing this request.
*/
static int VBoxNetAdpDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess)
{
int rc;
switch (IOCBASECMD(iCmd))
{
case IOCBASECMD(VBOXNETADP_CTL_ADD):
{
|| cbReq < sizeof(VBOXNETADPREQ))
return EINVAL;
if (RT_FAILURE(rc))
return EINVAL;
break;
}
case IOCBASECMD(VBOXNETADP_CTL_REMOVE):
{
return EINVAL;
if (!pAdp)
return EINVAL;
if (RT_FAILURE(rc))
return EINVAL;
break;
}
default:
return EINVAL;
}
return 0;
}
{
/*
* Init the darwin specific members.
*/
return VINF_SUCCESS;
}
/**
* Start the kernel module.
*/
{
int rc;
/*
* Initialize IPRT and find our module tag id.
* (IPRT is shared with VBoxDrv, it creates the loggers.)
*/
if (RT_SUCCESS(rc))
{
Log(("VBoxNetAdpDarwinStart\n"));
rc = vboxNetAdpInit();
if (RT_SUCCESS(rc))
{
if (g_nCtlDev < 0)
{
LogRel(("VBoxAdp: failed to register control device."));
}
else
{
if (!g_hCtlDev)
{
LogRel(("VBoxAdp: failed to create FS node for control device."));
}
}
}
if (RT_SUCCESS(rc))
{
return KMOD_RETURN_SUCCESS;
}
RTR0Term();
}
else
return KMOD_RETURN_FAILURE;
}
/**
* Stop the kernel module.
*/
{
Log(("VBoxNetAdpDarwinStop\n"));
/* Remove control device */
RTR0Term();
return KMOD_RETURN_SUCCESS;
}