/* $Id: VBoxNetAdpInternal.h 20374 2009-06-08 00:43:21Z vboxsync $ */ /** @file * VBoxNetAdp - Network Filter Driver (Host), Internal Header. */ /* * Copyright (C) 2008 Sun Microsystems, Inc. * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * 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. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 USA or visit http://www.sun.com if you need * additional information or have any questions. */ #ifndef ___VBoxNetAdpInternal_h___ #define ___VBoxNetAdpInternal_h___ #include #include #include #include RT_C_DECLS_BEGIN /** Pointer to the globals. */ typedef struct VBOXNETADPGLOBALS *PVBOXNETADPGLOBALS; #define VBOXNETADP_MAX_INSTANCES 8 #define VBOXNETADP_NAME "vboxnet" #define VBOXNETADP_MAX_NAME_LEN 32 #define VBOXNETADP_MTU 1500 #if defined(RT_OS_DARWIN) # define VBOXNETADP_MAX_FAMILIES 4 # define VBOXNETADP_DETACH_TIMEOUT 500 #endif #define VBOXNETADP_CTL_DEV_NAME "vboxnetctl" #define VBOXNETADP_CTL_ADD _IOR('v', 1, VBOXNETADPREQ) #define VBOXNETADP_CTL_REMOVE _IOW('v', 2, VBOXNETADPREQ) typedef struct VBoxNetAdpReq { char szName[VBOXNETADP_MAX_NAME_LEN]; } VBOXNETADPREQ; typedef VBOXNETADPREQ *PVBOXNETADPREQ; /** * Void entries mark vacant slots in adapter array. Valid entries are busy slots. * As soon as slot is being modified its state changes to transitional. * An entry in transitional state must only be accessed by the thread that * put it to this state. */ /** * To avoid races on adapter fields we stick to the following rules: * - rewrite: Int net port calls are serialized * - No modifications are allowed on busy adapters (deactivate first) * Refuse to destroy adapter until it gets to available state * - No transfers (thus getting busy) on inactive adapters * - Init sequence: void->available->connected->active 1) Create 2) Connect 3) Activate * - Destruction sequence: active->connected->available->void 1) Deactivate 2) Disconnect 3) Destroy */ enum VBoxNetAdpState { kVBoxNetAdpState_Invalid, kVBoxNetAdpState_Transitional, #ifdef VBOXANETADP_DO_NOT_USE_NETFLT kVBoxNetAdpState_Available, kVBoxNetAdpState_Connected, #endif /* VBOXANETADP_DO_NOT_USE_NETFLT */ kVBoxNetAdpState_Active, kVBoxNetAdpState_U32Hack = 0xFFFFFFFF }; typedef enum VBoxNetAdpState VBOXNETADPSTATE; struct VBoxNetAdapter { #ifdef VBOXANETADP_DO_NOT_USE_NETFLT /** The spinlock protecting the state variables and host interface handle. */ RTSPINLOCK hSpinlock; /* --- Protected with spinlock. --- */ #endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */ /** Denotes availability of this slot in adapter array. */ VBOXNETADPSTATE enmState; #ifdef VBOXANETADP_DO_NOT_USE_NETFLT /* --- Unprotected. Atomic access. --- */ /** Reference count. */ uint32_t volatile cRefs; /** The busy count. * This counts the number of current callers and pending packet. */ uint32_t volatile cBusy; /* --- Unprotected. Do not modify when cBusy > 0. --- */ /** Our RJ-45 port. * This is what the internal network plugs into. */ INTNETTRUNKIFPORT MyPort; /** The RJ-45 port on the INTNET "switch". * This is what we're connected to. */ PINTNETTRUNKSWPORT pSwitchPort; /** Pointer to the globals. */ PVBOXNETADPGLOBALS pGlobals; /** The event that is signaled when we go idle and that pfnWaitForIdle blocks on. */ RTSEMEVENT hEventIdle; #endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */ /** Corresponds to the digit at the end of device name. */ uint32_t uUnit; union { #ifdef VBOXNETADP_OS_SPECFIC struct { # if defined(RT_OS_DARWIN) /** @name Darwin instance data. * @{ */ /** Event to signal detachment of interface. */ RTSEMEVENT hEvtDetached; /** Pointer to Darwin interface structure. */ ifnet_t pIface; /** MAC address. */ RTMAC Mac; /** Protocol families attached to this adapter. */ protocol_family_t aAttachedFamilies[VBOXNETADP_MAX_FAMILIES]; /** @} */ # elif defined(RT_OS_LINUX) /** @name Darwin instance data. * @{ */ /** Pointer to Linux network device structure. */ struct net_device *pNetDev; /** @} */ # else # error PORTME # endif } s; #endif /** Padding. */ #if defined(RT_OS_WINDOWS) # if defined(VBOX_NETFLT_ONDEMAND_BIND) uint8_t abPadding[192]; # else uint8_t abPadding[1024]; # endif #elif defined(RT_OS_LINUX) uint8_t abPadding[64]; #else uint8_t abPadding[64]; #endif } u; /** The interface name. */ char szName[VBOXNETADP_MAX_NAME_LEN]; }; typedef struct VBoxNetAdapter VBOXNETADP; typedef VBOXNETADP *PVBOXNETADP; DECLHIDDEN(int) vboxNetAdpInit(void); DECLHIDDEN(void) vboxNetAdpShutdown(void); DECLHIDDEN(int) vboxNetAdpCreate (PVBOXNETADP *ppNew); DECLHIDDEN(int) vboxNetAdpDestroy(PVBOXNETADP pThis); DECLHIDDEN(PVBOXNETADP) vboxNetAdpFindByName(const char *pszName); #ifdef VBOXANETADP_DO_NOT_USE_NETFLT /** * The global data of the VBox filter driver. * * This contains the bit required for communicating with support driver, VBoxDrv * (start out as SupDrv). */ typedef struct VBOXNETADPGLOBALS { /** Mutex protecting the list of instances and state changes. */ RTSEMFASTMUTEX hFastMtx; /** Array of adapter instances. */ VBOXNETADP aAdapters[VBOXNETADP_MAX_INSTANCES]; /** The INTNET trunk network interface factory. */ INTNETTRUNKFACTORY TrunkFactory; /** The SUPDRV component factory registration. */ SUPDRVFACTORY SupDrvFactory; /** The number of current factory references. */ int32_t volatile cFactoryRefs; /** The SUPDRV IDC handle (opaque struct). */ SUPDRVIDCHANDLE SupDrvIDC; } VBOXNETADPGLOBALS; DECLHIDDEN(void) vboxNetAdpComposeMACAddress(PVBOXNETADP pThis, PRTMAC pMac); DECLHIDDEN(void) vboxNetAdpReceive(PVBOXNETADP pThis, PINTNETSG pSG); DECLHIDDEN(bool) vboxNetAdpPrepareToReceive(PVBOXNETADP pThis); DECLHIDDEN(void) vboxNetAdpCancelReceive(PVBOXNETADP pThis); DECLHIDDEN(int) vboxNetAdpInitGlobals(PVBOXNETADPGLOBALS pGlobals); DECLHIDDEN(int) vboxNetAdpTryDeleteGlobals(PVBOXNETADPGLOBALS pGlobals); DECLHIDDEN(bool) vboxNetAdpCanUnload(PVBOXNETADPGLOBALS pGlobals); DECLHIDDEN(void) vboxNetAdpRetain(PVBOXNETADP pThis); DECLHIDDEN(void) vboxNetAdpRelease(PVBOXNETADP pThis); DECLHIDDEN(void) vboxNetAdpBusy(PVBOXNETADP pThis); DECLHIDDEN(void) vboxNetAdpIdle(PVBOXNETADP pThis); DECLHIDDEN(int) vboxNetAdpInitGlobalsBase(PVBOXNETADPGLOBALS pGlobals); DECLHIDDEN(int) vboxNetAdpInitIdc(PVBOXNETADPGLOBALS pGlobals); DECLHIDDEN(void) vboxNetAdpDeleteGlobalsBase(PVBOXNETADPGLOBALS pGlobals); DECLHIDDEN(int) vboxNetAdpTryDeleteIdc(PVBOXNETADPGLOBALS pGlobals); /** @name The OS specific interface. * @{ */ /** * Transmits a frame. * * @return IPRT status code. * @param pThis The new instance. * @param pSG The (scatter/)gather list. * @param fDst The destination mask. At least one bit will be set. * * @remarks Owns the out-bound trunk port semaphore. */ DECLHIDDEN(int) vboxNetAdpPortOsXmit(PVBOXNETADP pThis, PINTNETSG pSG, uint32_t fDst); /** * Checks if the interface is in promiscuous mode from the host perspective. * * If it is, then the internal networking switch will send frames * heading for the wire to the host as well. * * @see INTNETTRUNKIFPORT::pfnIsPromiscuous for more details. * * @returns true / false accordingly. * @param pThis The instance. * * @remarks Owns the network lock and the out-bound trunk port semaphores. */ DECLHIDDEN(bool) vboxNetAdpPortOsIsPromiscuous(PVBOXNETADP pThis); /** * Get the MAC address of the interface we're attached to. * * Used by the internal networking switch for implementing the * shared-MAC-on-the-wire mode. * * @param pThis The instance. * @param pMac Where to store the MAC address. * If you don't know, set all the bits except the first (the multicast one). * * @remarks Owns the network lock and the out-bound trunk port semaphores. */ DECLHIDDEN(void) vboxNetAdpPortOsGetMacAddress(PVBOXNETADP pThis, PRTMAC pMac); /** * Checks if the specified MAC address is for any of the host interfaces. * * Used by the internal networking switch to decide the destination(s) * of a frame. * * @returns true / false accordingly. * @param pThis The instance. * @param pMac The MAC address. * * @remarks Owns the network lock and the out-bound trunk port semaphores. */ DECLHIDDEN(bool) vboxNetAdpPortOsIsHostMac(PVBOXNETADP pThis, PCRTMAC pMac); /** * This is called to when disconnecting from a network. * * @return IPRT status code. * @param pThis The new instance. * * @remarks May own the semaphores for the global list, the network lock and the out-bound trunk port. */ DECLHIDDEN(int) vboxNetAdpOsDisconnectIt(PVBOXNETADP pThis); /** * This is called to when connecting to a network. * * @return IPRT status code. * @param pThis The new instance. * * @remarks Owns the semaphores for the global list, the network lock and the out-bound trunk port. */ DECLHIDDEN(int) vboxNetAdpOsConnectIt(PVBOXNETADP pThis); /** @} */ #endif /* !VBOXANETADP_DO_NOT_USE_NETFLT */ /** * This is called to perform OS-specific structure initializations. * * @return IPRT status code. * @param pThis The new instance. * * @remarks Owns no locks. */ DECLHIDDEN(int) vboxNetAdpOsInit(PVBOXNETADP pThis); /** * Counter part to vboxNetAdpOsCreate(). * * @return IPRT status code. * @param pThis The new instance. * * @remarks May own the semaphores for the global list, the network lock and the out-bound trunk port. */ DECLHIDDEN(void) vboxNetAdpOsDestroy(PVBOXNETADP pThis); /** * This is called to attach to the actual host interface * after linking the instance into the list. * * @return IPRT status code. * @param pThis The new instance. * @param pMac The MAC address to use for this instance. * * @remarks Owns no locks. */ DECLHIDDEN(int) vboxNetAdpOsCreate(PVBOXNETADP pThis, PCRTMAC pMac); RT_C_DECLS_END #endif