Esempio n. 1
0
/*-
 * Called from the generic VFS startups.
 * This is the second stage of DEVFS initialisation.
 * The probed devices have already been loaded and the 
 * basic structure of the DEVFS created.
 * We take the oportunity to mount the hidden DEVFS layer, so that
 * devices from devfs get sync'd.
 */
static int
devfs_init(__unused struct vfsconf *vfsp)
{
    if (devfs_sinit())
	return (ENOTSUP);
    devfs_make_node(makedev(0, 0), DEVFS_CHAR, 
		    UID_ROOT, GID_WHEEL, 0622, "console");
    devfs_make_node(makedev(2, 0), DEVFS_CHAR, 
		    UID_ROOT, GID_WHEEL, 0666, "tty");
    if (setup_kmem) {
    	devfs_setup_kmem();
    }
    devfs_make_node(makedev(3, 2), DEVFS_CHAR, 
		    UID_ROOT, GID_WHEEL, 0666, "null");
    devfs_make_node(makedev(3, 3), DEVFS_CHAR, 
		    UID_ROOT, GID_WHEEL, 0666, "zero");
    devfs_make_node(makedev(6, 0), DEVFS_CHAR, 
		    UID_ROOT, GID_WHEEL, 0600, "klog");

#if  FDESC
    devfs_fdesc_init();
#endif

    return 0;
}
Esempio n. 2
0
__private_extern__ void
devfs_setup_kmem(void)
{
    	devfs_make_node(makedev(3, 0), DEVFS_CHAR, 
		    UID_ROOT, GID_KMEM, 0640, "mem");
    	devfs_make_node(makedev(3, 1), DEVFS_CHAR, 
		    UID_ROOT, GID_KMEM, 0640, "kmem");
}
Esempio n. 3
0
int
ddi_create_minor_node(dev_info_t *dip, char *name, int spec_type,
    minor_t minor_num, char *node_type, int flag)
{
	dev_t dev;
	int error=0;
    char *r, *dup;

	//printf("ddi_create_minor_node: name %s: %d,%d\n", name, flag, minor_num);

	dev = makedev(flag, minor_num);
    dip->dev = dev;

    /*
     * http://lists.apple.com/archives/darwin-kernel/2007/Nov/msg00038.html
     *
     * devfs_make_name() has an off-by-one error when using directories
     * and it appears Apple does not want to fix it.
     *
     * We then change "/" to "_" and create more Apple-like /dev names
     *
     */
    MALLOC(dup, char *, strlen(name)+1, M_TEMP, M_WAITOK);
    if (dup == NULL) return ENOMEM;
    bcopy(name, dup, strlen(name));
	dup[strlen(name)] = '\0';

    for (r = dup;
         (r=strchr(r, '/'));
         *r = '_') /* empty */ ;

    dip->devc = NULL;
    dip->devb = NULL;

	if (spec_type == S_IFCHR)
        dip->devc = devfs_make_node(dev, DEVFS_CHAR,   /* Make the node */
                                    UID_ROOT, GID_OPERATOR,
                                    0600, "rdisk_%s", dup);
    //0600, "rdisk3", dup);
	else
        dip->devb = devfs_make_node(dev, DEVFS_BLOCK,  /* Make the node */
                                    UID_ROOT, GID_OPERATOR,
                                    0600, "disk_%s", dup);
    //0600, "disk3", dup);

    //printf("ddi_create_minor: devfs_make_name '%s'\n", dup );

    FREE(dup, M_TEMP);

	return error;
}
Esempio n. 4
0
static void 
vndevice_do_init( void )
{
	int 	i;

	vndevice_bdev_major = bdevsw_add(BDEV_MAJOR, &vn_bdevsw);

	if (vndevice_bdev_major < 0) {
		printf("vndevice_init: bdevsw_add() returned %d\n",
		       vndevice_bdev_major);
		return;
	}
	vndevice_cdev_major = cdevsw_add_with_bdev(CDEV_MAJOR, &vn_cdevsw,
						   vndevice_bdev_major);
	if (vndevice_cdev_major < 0) {
		printf("vndevice_init: cdevsw_add() returned %d\n",
		       vndevice_cdev_major);
		return;
	}
	for (i = 0; i < NVNDEVICE; i++) {
		dev_t	dev = makedev(vndevice_bdev_major, i);
		vn_table[i].sc_bdev = devfs_make_node(dev, DEVFS_BLOCK,
						      UID_ROOT, GID_OPERATOR, 
						      0600, "vn%d", 
						      i);
		if (vn_table[i].sc_bdev == NULL)
			printf("vninit: devfs_make_node failed!\n");
	}
}
Esempio n. 5
0
/**
 * Register VBoxGuest char device
 */
static int vgdrvDarwinCharDevInit(void)
{
    int rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxGuestDarwin");
    if (RT_SUCCESS(rc))
    {
        /*
         * Registering ourselves as a character device.
         */
        g_iMajorDeviceNo = cdevsw_add(-1, &g_DevCW);
        if (g_iMajorDeviceNo >= 0)
        {
            g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
                                                UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_SYS);
            if (g_hDevFsDeviceSys != NULL)
            {
                /*
                 * Register a sleep/wakeup notification callback.
                 */
                g_pSleepNotifier = registerPrioritySleepWakeInterest(&vgdrvDarwinSleepHandler, &g_DevExt, NULL);
                if (g_pSleepNotifier != NULL)
                {
                    return KMOD_RETURN_SUCCESS;
                }
            }
        }
        vgdrvDarwinCharDevRemove();
    }
    return KMOD_RETURN_FAILURE;
}
Esempio n. 6
0
// Driver entry point. Initializes globals and registers driver node in /dev.
kern_return_t pmem_start(kmod_info_t * ki, void *d) {
  int error = 0;

  pmem_log("Loading /dev/%s driver", pmem_pmem_devname);
  // Memory allocations are tagged to prevent leaks
  pmem_tag = OSMalloc_Tagalloc(pmem_tagname, OSMT_DEFAULT);
  // Allocate one page for zero padding of illegal read requests
  pmem_zero_page = static_cast<uint8_t *>(OSMalloc(PAGE_SIZE, pmem_tag));
  if (pmem_zero_page == NULL) {
    pmem_error("Failed to allocate memory for page buffer");
    return pmem_cleanup(KERN_FAILURE);
  }
  bzero(pmem_zero_page, PAGE_SIZE);
  // Access the boot arguments through the platform export,
  // and parse the systems physical memory configuration.
  boot_args * ba = reinterpret_cast<boot_args *>(PE_state.bootArgs);
  pmem_physmem_size = ba->PhysicalMemorySize;
  pmem_mmap = reinterpret_cast<EfiMemoryRange *>(ba->MemoryMap +
                                                 pmem_kernel_voffset);
  pmem_mmap_desc_size = ba->MemoryMapDescriptorSize;
  pmem_mmap_size = ba->MemoryMapSize;
  pmem_log("Size of physical memory:%lld", pmem_physmem_size);
  pmem_log("Size of physical pages:%d (PAGE_SHIFT=%d, PAGE_MASK=%#016x)",
           PAGE_SIZE, PAGE_SHIFT, PAGE_MASK);
  pmem_log("Phys. Memory map at:%#016llx (size:%lld desc_size:%d)",
           pmem_mmap, pmem_mmap_size, pmem_mmap_desc_size);
  pmem_log("Number of segments in memory map: %d",
           pmem_mmap_size / pmem_mmap_desc_size);
  // Install switch table
  pmem_devmajor = cdevsw_add(-1, &pmem_cdevsw);
  if (pmem_devmajor == -1) {
    pmem_error("Failed to create character device");
    return pmem_cleanup(KERN_FAILURE);
  }
  // Create physical memory device file
  pmem_log("Adding node /dev/%s", pmem_pmem_devname);
  pmem_devpmemnode = devfs_make_node(makedev(pmem_devmajor,
                                             pmem_dev_pmem_minor),
                                     DEVFS_CHAR,
                                     UID_ROOT,
                                     GID_WHEEL,
                                     0660,
                                     pmem_pmem_devname);
  if (pmem_devpmemnode == NULL) {
    pmem_error("Failed to create /dev/%s node", pmem_pmem_devname);
    return pmem_cleanup(KERN_FAILURE);
  }
  pmem_log("obtaining kernel dtb pointer");
  __asm__ __volatile__("movq %%cr3, %0" :"=r"(pmem_dtb));
  // Only bits 51-12 (inclusive) in cr3 are part of the dtb pointer
  pmem_dtb &= ~PAGE_MASK;
  pmem_log("kernel dtb: %#016llx", pmem_dtb);
  pmem_log("initializing pte_mmap module");
  pmem_log("pmem driver loaded, physical memory available in /dev/%s",
           pmem_pmem_devname);

  return error;
}
Esempio n. 7
0
int
ddi_create_minor_node(dev_info_t *dip, const char *name, int spec_type,
    minor_t minor_num, const char *node_type, int flag)
{
#pragma unused(spec_type,node_type,flag)
	dev_t dev = makedev( (uint32_t)dip, minor_num );

	if (NULL == devfs_make_node( dev, DEVFS_CHAR, UID_ROOT, GID_WHEEL, 0666, name, 0 ))
		return DDI_FAILURE;
	else
		return DDI_SUCCESS;
} 
Esempio n. 8
0
kern_return_t OsqueryStart(kmod_info_t *ki, void *d) {
  dbg_printf("Kernel module starting!\n");

  // Restart the queue and setup queue locks.
  // This does not allocate, share, or set the queue buffer or buffer values.
  osquery_cqueue_setup(&osquery.cqueue);

  // Initialize the IOCTL (and more) device node.
  osquery.major_number = cdevsw_add(osquery.major_number, &osquery_cdevsw);
  if (osquery.major_number < 0) {
    dbg_printf("Could not get a major number!\n");
    goto error_exit;
  }

  // Create the IOCTL (and more) device node.
  osquery.devfs = devfs_make_node(makedev(osquery.major_number, 0),
                                  DEVFS_CHAR,
                                  UID_ROOT,
                                  GID_WHEEL,
                                  0600,
                                  "osquery",
                                  0);
  if (osquery.devfs == NULL) {
    dbg_printf("Could not get a devfs entry!\n");
    goto error_exit;
  }

  // Set up the IOCTL and kernel API locks (not queue locks).
  setup_locks();

  return KERN_SUCCESS;
error_exit:
  // Upon error, remove the device node if it was allocated.
  if (osquery.devfs != NULL) {
    devfs_remove(osquery.devfs);
    osquery.devfs = NULL;
  }

  // Tear down device node data.
  if (!(osquery.major_number < 0)) {
    if (cdevsw_remove(osquery.major_number, &osquery_cdevsw) < 0) {
      panic("osquery kext: Cannot remove osquery from cdevsw");
    }
  }

  // Reset the queue and remove the queue locks.
  osquery_cqueue_teardown(&osquery.cqueue);
  return KERN_FAILURE;
}
/**
 * Start the kernel module.
 */
static kern_return_t    VBoxNetAdpDarwinStart(struct kmod_info *pKModInfo, void *pvData)
{
    int rc;

    /*
     * Initialize IPRT and find our module tag id.
     * (IPRT is shared with VBoxDrv, it creates the loggers.)
     */
    rc = RTR0Init(0);
    if (RT_SUCCESS(rc))
    {
        Log(("VBoxNetAdpDarwinStart\n"));
        rc = vboxNetAdpInit();
        if (RT_SUCCESS(rc))
        {
            g_nCtlDev = cdevsw_add(-1, &g_ChDev);
            if (g_nCtlDev < 0)
            {
                LogRel(("VBoxAdp: failed to register control device."));
                rc = VERR_CANT_CREATE;
            }
            else
            {
                g_hCtlDev = devfs_make_node(makedev(g_nCtlDev, 0), DEVFS_CHAR,
                                            UID_ROOT, GID_WHEEL, 0600, VBOXNETADP_CTL_DEV_NAME);
                if (!g_hCtlDev)
                {
                    LogRel(("VBoxAdp: failed to create FS node for control device."));
                    rc = VERR_CANT_CREATE;
                }
            }
        }

        if (RT_SUCCESS(rc))
        {
            LogRel(("VBoxAdpDrv: version " VBOX_VERSION_STRING " r%d\n", VBOX_SVN_REV));
            return KMOD_RETURN_SUCCESS;
        }

        LogRel(("VBoxAdpDrv: failed to initialize device extension (rc=%d)\n", rc));
        RTR0Term();
    }
    else
        printf("VBoxAdpDrv: failed to initialize IPRT (rc=%d)\n", rc);

    return KMOD_RETURN_FAILURE;
}
Esempio n. 10
0
bool
IOSCSITape::InitializeDeviceSupport(void)
{
	if (FindDeviceMinorNumber())
	{
		cdev_node = devfs_make_node(
									makedev(CdevMajorIniter.majorNumber, tapeNumber), 
									DEVFS_CHAR,
									UID_ROOT,
									GID_OPERATOR,
									0664,
									TAPE_FORMAT, tapeNumber);
		
		if (cdev_node)
		{
			flags = 0;
			
			return true;
		}
	}
	
	return false;
}
Esempio n. 11
0
kern_return_t OsqueryStart(kmod_info_t *ki, void *d) {
    dbg_printf("Kernel module starting!\n");

    osquery_cqueue_setup(&osquery.cqueue);

    osquery.major_number = cdevsw_add(osquery.major_number, &osquery_cdevsw);
    if (osquery.major_number < 0) {
        dbg_printf("Could not get a major number!\n");
        goto error_exit;
    }

    osquery.devfs = devfs_make_node(makedev(osquery.major_number, 0),
                                    DEVFS_CHAR, UID_ROOT, GID_WHEEL,
                                    0644, "osquery", 0);
    if (osquery.devfs == NULL) {
        dbg_printf("Could not get a devfs entry!\n");
        goto error_exit;
    }

    setup_locks();

    return KERN_SUCCESS;
error_exit:
    if (osquery.devfs != NULL) {
        devfs_remove(osquery.devfs);
        osquery.devfs = NULL;
    }

    if (!(osquery.major_number < 0)) {
        if (cdevsw_remove(osquery.major_number, &osquery_cdevsw) < 0) {
            panic("osquery kext: Cannot remove osquery from cdevsw");
        }
    }

    osquery_cqueue_teardown(&osquery.cqueue);
    return KERN_FAILURE;
}
Esempio n. 12
0
// Driver entry point. Initializes globals and registers driver node in /dev.
kern_return_t chipsec_start(kmod_info_t * ki, void *d) {
    int error = 0;

    pmem_log("Loading /dev/%s driver", chipsec_devname);
    // Memory allocations are tagged to prevent leaks
    pmem_tag = OSMalloc_Tagalloc(pmem_tagname, OSMT_DEFAULT);
    // Allocate one page for zero padding of illegal read requests
    pmem_zero_page = static_cast<uint8_t *>(OSMalloc(PAGE_SIZE, pmem_tag));
    if (pmem_zero_page == NULL) {
        pmem_error("Failed to allocate memory for page buffer");
        return pmem_cleanup(KERN_FAILURE);
    }
    bzero(pmem_zero_page, PAGE_SIZE);

    // Install the character device
    chipsec_dev_major = cdevsw_add(-1, &pmem_cdevsw);
    if (chipsec_dev_major == -1) {
        pmem_error("Failed to create character device");
        return pmem_cleanup(KERN_FAILURE);
    }
    // Create physical memory device file
    pmem_log("Adding node /dev/%s", chipsec_devname);
    pmem_devpmemnode = devfs_make_node(makedev(chipsec_dev_major,
                                               chipsec_dev_minor),
                                       DEVFS_CHAR,
                                       UID_ROOT,
                                       GID_WHEEL,
                                       0660,
                                       chipsec_devname);
    if (pmem_devpmemnode == NULL) {
        pmem_error("Failed to create /dev/%s node", chipsec_devname);
        return pmem_cleanup(KERN_FAILURE);
    }
    pmem_log("pmem driver loaded, physical memory available in /dev/%s",
             chipsec_devname);
    return error;
}
Esempio n. 13
0
static int
nsmb_dev_open_nolock(dev_t dev, int oflags, int devtype, struct proc *p)
{
#pragma unused(oflags, devtype, p)
	struct smb_dev *sdp;
	kauth_cred_t cred = vfs_context_ucred(vfs_context_current());

	sdp = SMB_GETDEV(dev);
	if (sdp && (sdp->sd_flags & NSMBFL_OPEN))
		return (EBUSY);
	if (!sdp || minor(dev) == 0) {
		int	avail_minor;

		for (avail_minor = 1; avail_minor < SMBMINORS; avail_minor++)
			if (!SMB_GETDEV(avail_minor))
				break;
		if (avail_minor >= SMBMINORS) {
			SMBERROR("Too many minor devices, %d >= %d !", avail_minor, SMBMINORS);
			return (ENOMEM);
		}
        SMB_MALLOC(sdp, struct smb_dev *, sizeof(*sdp), M_NSMBDEV, M_WAITOK);
		bzero(sdp, sizeof(*sdp));
		dev = makedev(smb_major, avail_minor);
		sdp->sd_devfs = devfs_make_node(dev, DEVFS_CHAR,
						kauth_cred_getuid(cred),
						kauth_cred_getgid(cred),
						0700, "nsmb%x", avail_minor);
		if (!sdp->sd_devfs) {
			SMBERROR("devfs_make_node failed %d\n", avail_minor);
			SMB_FREE(sdp, M_NSMBDEV);
			return (ENOMEM);
		}
		if (avail_minor > smb_minor_hiwat)
			smb_minor_hiwat = avail_minor;
		SMB_GETDEV(dev) = sdp;
		return (EBUSY);
	}
Esempio n. 14
0
static int
vniocattach_file(struct vn_softc *vn,
		 struct vn_ioctl_64 *vniop,
		 dev_t dev,
		 int in_kernel,
		 proc_t p)
{
	dev_t	cdev;
	vfs_context_t ctx = vfs_context_current();
	kauth_cred_t cred;
	struct nameidata nd;
	off_t file_size;
	int error, flags;

	flags = FREAD|FWRITE;
	if (in_kernel) {
		NDINIT(&nd, LOOKUP, OP_OPEN, FOLLOW, UIO_SYSSPACE, vniop->vn_file, ctx);
	}
	else {
		NDINIT(&nd, LOOKUP, OP_OPEN, FOLLOW, 
			   (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32), 
			   vniop->vn_file, ctx);
	}
	/* vn_open gives both long- and short-term references */
	error = vn_open(&nd, flags, 0);
	if (error) {
		if (error != EACCES && error != EPERM && error != EROFS) {
			return (error);
		}
		flags &= ~FWRITE;
		if (in_kernel) {
			NDINIT(&nd, LOOKUP, OP_OPEN, FOLLOW, UIO_SYSSPACE, 
			       vniop->vn_file, ctx);
		}
		else {
			NDINIT(&nd, LOOKUP, OP_OPEN, FOLLOW, 
				   (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32), 
			       vniop->vn_file, ctx);
		}
		error = vn_open(&nd, flags, 0);
		if (error) {
			return (error);
		}
	}
	if (nd.ni_vp->v_type != VREG) {
		error = EINVAL;
	}
	else {
		error = vnode_size(nd.ni_vp, &file_size, ctx);
	}
	if (error != 0) {
		(void) vn_close(nd.ni_vp, flags, ctx);
		vnode_put(nd.ni_vp);
		return (error);
	}
	cred = kauth_cred_proc_ref(p);
	nd.ni_vp->v_flag |= VNOCACHE_DATA;
	error = setcred(nd.ni_vp, cred);
	if (error) {
		(void)vn_close(nd.ni_vp, flags, ctx);
		vnode_put(nd.ni_vp);
		kauth_cred_unref(&cred);
		return(error);
	}
	vn->sc_secsize = DEV_BSIZE;
	vn->sc_fsize = file_size;
	vn->sc_size = file_size / vn->sc_secsize;
	vn->sc_vp = nd.ni_vp;
	vn->sc_vid = vnode_vid(nd.ni_vp);
	vn->sc_open_flags = flags;
	vn->sc_cred = cred;
	cdev = makedev(vndevice_cdev_major, minor(dev));
	vn->sc_cdev = devfs_make_node(cdev, DEVFS_CHAR,
				      UID_ROOT, GID_OPERATOR, 
				      0600, "rvn%d", 
				      minor(dev));
	vn->sc_flags |= VNF_INITED;
	if (flags == FREAD)
		vn->sc_flags |= VNF_READONLY;
	/* lose the short-term reference */
	vnode_put(nd.ni_vp);
	return(0);
}
Esempio n. 15
0
/**
 * Start the kernel module.
 */
static kern_return_t    VBoxDrvDarwinStart(struct kmod_info *pKModInfo, void *pvData)
{
    int rc;
#ifdef DEBUG
    printf("VBoxDrvDarwinStart\n");
#endif

    /*
     * Initialize IPRT.
     */
    rc = RTR0Init(0);
    if (RT_SUCCESS(rc))
    {
        /*
         * Initialize the device extension.
         */
        rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
        if (RT_SUCCESS(rc))
        {
            /*
             * Initialize the session hash table.
             */
            memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab)); /* paranoia */
            rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvDarwin");
            if (RT_SUCCESS(rc))
            {
                /*
                 * Registering ourselves as a character device.
                 */
                g_iMajorDeviceNo = cdevsw_add(-1, &g_DevCW);
                if (g_iMajorDeviceNo >= 0)
                {
#ifdef VBOX_WITH_HARDENING
                    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
                                                        UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME_SYS);
#else
                    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
                                                        UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_SYS);
#endif
                    if (g_hDevFsDeviceSys)
                    {
                        g_hDevFsDeviceUsr = devfs_make_node(makedev(g_iMajorDeviceNo, 1), DEVFS_CHAR,
                                                            UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_USR);
                        if (g_hDevFsDeviceUsr)
                        {
                            LogRel(("VBoxDrv: version " VBOX_VERSION_STRING " r%d; IOCtl version %#x; IDC version %#x; dev major=%d\n",
                                    VBOX_SVN_REV, SUPDRV_IOC_VERSION, SUPDRV_IDC_VERSION, g_iMajorDeviceNo));

                            /* Register a sleep/wakeup notification callback */
                            g_pSleepNotifier = registerPrioritySleepWakeInterest(&VBoxDrvDarwinSleepHandler, &g_DevExt, NULL);
                            if (g_pSleepNotifier == NULL)
                                LogRel(("VBoxDrv: register for sleep/wakeup events failed\n"));

                            /* Find kernel symbols that are kind of optional. */
                            vboxdrvDarwinResolveSymbols();
                            return KMOD_RETURN_SUCCESS;
                        }

                        LogRel(("VBoxDrv: devfs_make_node(makedev(%d,1),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_USR));
                        devfs_remove(g_hDevFsDeviceSys);
                        g_hDevFsDeviceSys = NULL;
                    }
                    else
                        LogRel(("VBoxDrv: devfs_make_node(makedev(%d,0),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_SYS));

                    cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
                    g_iMajorDeviceNo = -1;
                }
                else
                    LogRel(("VBoxDrv: cdevsw_add failed (%d)\n", g_iMajorDeviceNo));
                RTSpinlockDestroy(g_Spinlock);
                g_Spinlock = NIL_RTSPINLOCK;
            }
            else
                LogRel(("VBoxDrv: RTSpinlockCreate failed (rc=%d)\n", rc));
            supdrvDeleteDevExt(&g_DevExt);
        }
        else
            printf("VBoxDrv: failed to initialize device extension (rc=%d)\n", rc);
        RTR0TermForced();
    }
    else
        printf("VBoxDrv: failed to initialize IPRT (rc=%d)\n", rc);

    memset(&g_DevExt, 0, sizeof(g_DevExt));
    return KMOD_RETURN_FAILURE;
}
Esempio n. 16
0
File: bpf.c Progetto: SbIm/xnu-env
static int
bpf_movein(struct uio *uio, int linktype, struct mbuf **mp, struct sockaddr *sockp, int *datlen)
{
	struct mbuf *m;
	int error;
	int len;
	uint8_t sa_family;
	int hlen;

	switch (linktype) {
	
#if SLIP
	case DLT_SLIP:
		sa_family = AF_INET;
		hlen = 0;
		break;
#endif /* SLIP */
	
	case DLT_EN10MB:
		sa_family = AF_UNSPEC;
		/* XXX Would MAXLINKHDR be better? */
		hlen = sizeof(struct ether_header);
		break;
	
#if FDDI
	case DLT_FDDI:
	#if defined(__FreeBSD__) || defined(__bsdi__)
		sa_family = AF_IMPLINK;
		hlen = 0;
	#else
		sa_family = AF_UNSPEC;
		/* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */
		hlen = 24;
	#endif
		break;
#endif /* FDDI */
	
	case DLT_RAW:
	case DLT_NULL:
		sa_family = AF_UNSPEC;
		hlen = 0;
		break;
	
	#ifdef __FreeBSD__
	case DLT_ATM_RFC1483:
		/*
		 * en atm driver requires 4-byte atm pseudo header.
		 * though it isn't standard, vpi:vci needs to be
		 * specified anyway.
		 */
		sa_family = AF_UNSPEC;
		hlen = 12; 	/* XXX 4(ATM_PH) + 3(LLC) + 5(SNAP) */
		break;
	#endif

	case DLT_PPP:
		sa_family = AF_UNSPEC;
		hlen = 4;	/* This should match PPP_HDRLEN */
		break;
	
	case DLT_APPLE_IP_OVER_IEEE1394:
		sa_family = AF_UNSPEC;
		hlen = sizeof(struct firewire_header);
		break;

	case DLT_IEEE802_11:            /* IEEE 802.11 wireless */
		sa_family = AF_IEEE80211;
		hlen = 0;
		break;

	default:
		return (EIO);
	}

	// LP64todo - fix this!
	len = uio_resid(uio);
	*datlen = len - hlen;
	if ((unsigned)len > MCLBYTES)
		return (EIO);

	if (sockp) {
		/*
		 * Build a sockaddr based on the data link layer type.
		 * We do this at this level because the ethernet header
		 * is copied directly into the data field of the sockaddr.
		 * In the case of SLIP, there is no header and the packet
		 * is forwarded as is.
		 * Also, we are careful to leave room at the front of the mbuf
		 * for the link level header.
		 */
		if ((hlen + SOCKADDR_HDR_LEN) > sockp->sa_len) {
			return (EIO);
		}
		sockp->sa_family = sa_family;
	} else {
		/*
		 * We're directly sending the packet data supplied by
		 * the user; we don't need to make room for the link
		 * header, and don't need the header length value any
		 * more, so set it to 0.
		 */
		hlen = 0;
	}
	
	MGETHDR(m, M_WAIT, MT_DATA);
	if (m == 0)
		return (ENOBUFS);
	if ((unsigned)len > MHLEN) {
#if BSD >= 199103
		MCLGET(m, M_WAIT);
		if ((m->m_flags & M_EXT) == 0) {
#else
		MCLGET(m);
		if (m->m_len != MCLBYTES) {
#endif
			error = ENOBUFS;
			goto bad;
		}
	}
	m->m_pkthdr.len = m->m_len = len;
	m->m_pkthdr.rcvif = NULL;
	*mp = m;
	/*
	 * Make room for link header.
	 */
	if (hlen != 0) {
		m->m_pkthdr.len -= hlen;
		m->m_len -= hlen;
#if BSD >= 199103
		m->m_data += hlen; /* XXX */
#else
		m->m_off += hlen;
#endif
		error = UIOMOVE((caddr_t)sockp->sa_data, hlen, UIO_WRITE, uio);
		if (error)
			goto bad;
	}
	error = UIOMOVE(mtod(m, caddr_t), len - hlen, UIO_WRITE, uio);
	if (!error)
		return (0);
 bad:
	m_freem(m);
	return (error);
}

#ifdef __APPLE__

/*
 * The dynamic addition of a new device node must block all processes that are opening 
 * the last device so that no process will get an unexpected ENOENT 
 */
static void
bpf_make_dev_t(int maj)
{
	static int		bpf_growing = 0;
	unsigned int	cur_size = nbpfilter, i;

	if (nbpfilter >= bpf_maxdevices)
		return;

	while (bpf_growing) {
		/* Wait until new device has been created */
		(void)tsleep((caddr_t)&bpf_growing, PZERO, "bpf_growing", 0);
	}
	if (nbpfilter > cur_size) {
		/* other thread grew it already */
		return;
	}
	bpf_growing = 1;
	
	/* need to grow bpf_dtab first */
	if (nbpfilter == bpf_dtab_size) {
		int new_dtab_size;
		struct bpf_d **new_dtab = NULL;
		struct bpf_d **old_dtab = NULL;
		
		new_dtab_size = bpf_dtab_size + NBPFILTER;	
		new_dtab = (struct bpf_d **)_MALLOC(sizeof(struct bpf_d *) * new_dtab_size, M_DEVBUF, M_WAIT);
		if (new_dtab == 0) {
			printf("bpf_make_dev_t: malloc bpf_dtab failed\n");
			goto done;
		}
		if (bpf_dtab) {
			bcopy(bpf_dtab, new_dtab, 
				  sizeof(struct bpf_d *) * bpf_dtab_size);
		}
		bzero(new_dtab + bpf_dtab_size, 
			  sizeof(struct bpf_d *) * NBPFILTER);
		old_dtab = bpf_dtab;
		bpf_dtab = new_dtab;
		bpf_dtab_size = new_dtab_size;
		if (old_dtab != NULL)
			_FREE(old_dtab, M_DEVBUF);
	}
	i = nbpfilter++;
	(void) devfs_make_node(makedev(maj, i),
				DEVFS_CHAR, UID_ROOT, GID_WHEEL, 0600,
				"bpf%d", i);
done:
	bpf_growing = 0;
	wakeup((caddr_t)&bpf_growing);
}

#endif

/*
 * Attach file to the bpf interface, i.e. make d listen on bp.
 */
static errno_t
bpf_attachd(struct bpf_d *d, struct bpf_if *bp)
{
	int first = bp->bif_dlist == NULL;
	int	error = 0;
	
	/*
	 * Point d at bp, and add d to the interface's list of listeners.
	 * Finally, point the driver's bpf cookie at the interface so
	 * it will divert packets to bpf.
	 */
	d->bd_bif = bp;
	d->bd_next = bp->bif_dlist;
	bp->bif_dlist = d;
	
	if (first) {
		/* Find the default bpf entry for this ifp */
		if (bp->bif_ifp->if_bpf == NULL) {
			struct bpf_if	*primary;
			
			for (primary = bpf_iflist; primary && primary->bif_ifp != bp->bif_ifp;
				 primary = primary->bif_next)
				;
		
			bp->bif_ifp->if_bpf = primary;
		}
		
		/* Only call dlil_set_bpf_tap for primary dlt */
		if (bp->bif_ifp->if_bpf == bp)
			dlil_set_bpf_tap(bp->bif_ifp, BPF_TAP_INPUT_OUTPUT, bpf_tap_callback);
		
		if (bp->bif_tap)
			error = bp->bif_tap(bp->bif_ifp, bp->bif_dlt, BPF_TAP_INPUT_OUTPUT);
	}

	return error;
}