VBoxNetAdp-freebsd.c revision 83365ff77c1571f994b3a15bfbdee077d2ea8a07
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync/* $Id$ */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync/** @file
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * VBoxNetAdp - Virtual Network Adapter Driver (Host), FreeBSD Specific Code.
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync/*-
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * Copyright (c) 2009 Fredrik Lindberg <fli@shapeshifter.se>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync *
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * Permission is hereby granted, free of charge, to any person
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * obtaining a copy of this software and associated documentation
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * files (the "Software"), to deal in the Software without
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * restriction, including without limitation the rights to use,
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * copy, modify, merge, publish, distribute, sublicense, and/or sell
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * copies of the Software, and to permit persons to whom the
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * Software is furnished to do so, subject to the following
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * conditions:
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync *
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * The above copyright notice and this permission notice shall be
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * included in all copies or substantial portions of the Software.
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync *
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
9d0256d0854254b2717550a64a6e5871a1123a0dvboxsync * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync * OTHER DEALINGS IN THE SOFTWARE.
35396ee506ef68dd1c161f1ef2c3c0b68a146ff2vboxsync */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync/*******************************************************************************
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync* Header Files *
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync*******************************************************************************/
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <sys/param.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#undef PVM
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <sys/types.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <sys/module.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <sys/systm.h>
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync#include <sys/errno.h>
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync#include <sys/kernel.h>
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync#include <sys/fcntl.h>
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync#include <sys/conf.h>
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync#include <sys/uio.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <sys/socket.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <sys/sockio.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <net/if.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <net/if_var.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <net/route.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <net/if_dl.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <net/if_types.h>
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync#include <net/ethernet.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <net/bpf.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#define LOG_GROUP LOG_GROUP_NET_ADP_DRV
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <VBox/version.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <VBox/err.h>
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync#include <VBox/log.h>
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync#include <iprt/initterm.h>
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync#include <iprt/string.h>
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync#include <iprt/spinlock.h>
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync#include <iprt/process.h>
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync#include <iprt/assert.h>
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync#include <iprt/uuid.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <iprt/alloc.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <iprt/err.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#define VBOXNETADP_OS_SPECFIC 1
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include "../VBoxNetAdpInternal.h"
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsyncstatic int VBoxNetAdpFreeBSDCtrlioctl(struct cdev *, u_long, caddr_t, int flags,
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync struct thread *);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsyncstatic struct cdevsw vboxnetadp_cdevsw =
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync .d_version = D_VERSION,
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync .d_ioctl = VBoxNetAdpFreeBSDCtrlioctl,
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync .d_read = (d_read_t *)nullop,
87719ea227ff5749eed4101abe8c06c86f24690dvboxsync .d_write = (d_write_t *)nullop,
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync .d_name = VBOXNETADP_CTL_DEV_NAME,
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync};
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsyncstatic struct cdev *VBoxNetAdpFreeBSDcdev;
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsyncstatic int VBoxNetAdpFreeBSDModuleEvent(struct module *, int, void *);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsyncstatic moduledata_t g_VBoxNetAdpFreeBSDModule = {
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync "vboxnetadp",
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync VBoxNetAdpFreeBSDModuleEvent,
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync NULL
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync};
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync/** Declare the module as a pseudo device. */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsyncDECLARE_MODULE(vboxnetadp, g_VBoxNetAdpFreeBSDModule, SI_SUB_PSEUDO, SI_ORDER_ANY);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsyncMODULE_VERSION(vboxnetadp, 1);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsyncMODULE_DEPEND(vboxnetadp, vboxdrv, 1, 1, 1);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsyncMODULE_DEPEND(vboxnetadp, vboxnetflt, 1, 1, 1);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
87719ea227ff5749eed4101abe8c06c86f24690dvboxsync/**
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync * Module event handler
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsyncstatic int
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsyncVBoxNetAdpFreeBSDModuleEvent(struct module *pMod, int enmEventType, void *pvArg)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync int rc = 0;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync Log(("VBoxNetAdpFreeBSDModuleEvent\n"));
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync
87719ea227ff5749eed4101abe8c06c86f24690dvboxsync switch (enmEventType)
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync {
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync case MOD_LOAD:
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync rc = RTR0Init(0);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (RT_FAILURE(rc))
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync Log(("RTR0Init failed %d\n", rc));
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return RTErrConvertToErrno(rc);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync rc = vboxNetAdpInit();
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (RT_FAILURE(rc))
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync RTR0Term();
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync Log(("vboxNetAdpInit failed %d\n", rc));
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return RTErrConvertToErrno(rc);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync /* Create dev node */
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync VBoxNetAdpFreeBSDcdev = make_dev(&vboxnetadp_cdevsw, 0,
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync UID_ROOT, GID_WHEEL, 0600, VBOXNETADP_CTL_DEV_NAME);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync break;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync case MOD_UNLOAD:
87719ea227ff5749eed4101abe8c06c86f24690dvboxsync vboxNetAdpShutdown();
87719ea227ff5749eed4101abe8c06c86f24690dvboxsync destroy_dev(VBoxNetAdpFreeBSDcdev);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync RTR0Term();
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync break;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync case MOD_SHUTDOWN:
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync case MOD_QUIESCE:
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync default:
87719ea227ff5749eed4101abe8c06c86f24690dvboxsync return EOPNOTSUPP;
87719ea227ff5749eed4101abe8c06c86f24690dvboxsync }
87719ea227ff5749eed4101abe8c06c86f24690dvboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (RT_SUCCESS(rc))
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return 0;
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync return RTErrConvertToErrno(rc);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync/**
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync * Device I/O Control entry point.
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsyncstatic int
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsyncVBoxNetAdpFreeBSDCtrlioctl(struct cdev *dev, u_long iCmd, caddr_t data, int flags, struct thread *td)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync PVBOXNETADP pAdp;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync PVBOXNETADPREQ pReq = (PVBOXNETADPREQ)data;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync struct ifnet *ifp;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync int rc;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync switch (iCmd)
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync {
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync case VBOXNETADP_CTL_ADD:
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if ( !(iCmd & IOC_OUT) /* paranoia*/
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync || IOCPARM_LEN(iCmd) < sizeof(*pReq))
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return EINVAL;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync rc = vboxNetAdpCreate(&pAdp, NULL);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (RT_FAILURE(rc))
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return EINVAL;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync strncpy(pReq->szName, pAdp->szName, sizeof(pReq->szName) - 1);
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync pReq->szName[sizeof(pReq->szName) - 1] = '\0';
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync break;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync case VBOXNETADP_CTL_REMOVE:
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync if (!RTStrEnd(pReq->szName, RT_MIN(sizeof(pReq->szName), IOCPARM_LEN(iCmd))))
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync return EINVAL;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync pAdp = vboxNetAdpFindByName(pReq->szName);
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync if (!pAdp)
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync return EINVAL;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync rc = vboxNetAdpDestroy(pAdp);
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync if (RT_FAILURE(rc))
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync return EINVAL;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync break;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync default:
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync return EINVAL;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync }
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync return 0;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync}
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync/**
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync * Initialize device, just set the running flag.
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync */
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsyncstatic void VBoxNetAdpFreeBSDNetinit(void *priv)
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync{
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync PVBOXNETADP pThis = priv;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync struct ifnet *ifp = pThis->u.s.ifp;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync ifp->if_drv_flags |= IFF_DRV_RUNNING;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync}
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync/**
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync * Transmit packets.
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync * netflt has already done everything for us so we just hand the
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync * packets to BPF and increment the packet stats.
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync */
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsyncstatic void VBoxNetAdpFreeBSDNetstart(struct ifnet *ifp)
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync{
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync PVBOXNETADP pThis = ifp->if_softc;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync struct mbuf *m;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING)
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync return;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync ifp->if_drv_flags |= IFF_DRV_OACTIVE;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync {
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync ifp->if_opackets++;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync BPF_MTAP(ifp, m);
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync m_freem(m);
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync }
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync}
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync/**
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync * Interface ioctl handling
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync */
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsyncstatic int VBoxNetAdpFreeBSDNetioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync switch (cmd)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync case SIOCSIFFLAGS:
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (ifp->if_flags & IFF_UP)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ifp->if_init(ifp->if_softc);
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync else
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync if (ifp->if_drv_flags & IFF_DRV_RUNNING)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync break;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync default:
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return ether_ioctl(ifp, cmd, data);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return 0;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsyncint vboxNetAdpOsInit(PVBOXNETADP pThis)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync pThis->u.s.ifp = NULL;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return VINF_SUCCESS;;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsyncint vboxNetAdpOsCreate(PVBOXNETADP pThis, PCRTMAC pMac, const char *pcszName)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync /* TODO: Use pcszName */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync struct ifnet *ifp;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ifp = if_alloc(IFT_ETHER);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (ifp == NULL)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return VERR_NO_MEMORY;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if_initname(ifp, VBOXNETADP_NAME, pThis->nUnit);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ifp->if_softc = pThis;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ifp->if_mtu = ETHERMTU;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
f65e6cba3e74ffd3dc9e6053828dcc82b367e8devboxsync ifp->if_ioctl = VBoxNetAdpFreeBSDNetioctl;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ifp->if_start = VBoxNetAdpFreeBSDNetstart;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ifp->if_init = VBoxNetAdpFreeBSDNetinit;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync IFQ_SET_READY(&ifp->if_snd);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ether_ifattach(ifp, (void *)pMac);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ifp->if_baudrate = 0;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync strncpy(pThis->szName, ifp->if_xname, VBOXNETADP_MAX_NAME_LEN);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync pThis->u.s.ifp = ifp;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return 0;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsyncvoid vboxNetAdpOsDestroy(PVBOXNETADP pThis)
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync{
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync struct ifnet *ifp;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ifp = pThis->u.s.ifp;
36c5021c9ff03eb19d9818903cea95d2e43bd6bcvboxsync ether_ifdetach(ifp);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if_free(ifp);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync