示例#1
0
static int
ntfs_mountroot(void)
{
	struct mount *mp;
	struct lwp *l = curlwp;	/* XXX */
	int error;
	struct ntfs_args args;

	if (device_class(root_device) != DV_DISK)
		return (ENODEV);

	if ((error = vfs_rootmountalloc(MOUNT_NTFS, "root_device", &mp))) {
		vrele(rootvp);
		return (error);
	}

	args.flag = 0;
	args.uid = 0;
	args.gid = 0;
	args.mode = 0777;

	if ((error = ntfs_mountfs(rootvp, mp, &args, l)) != 0) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		return (error);
	}

	mountlist_append(mp);
	(void)ntfs_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	return (0);
}
示例#2
0
文件: bluelog.c 项目: naranek/Bluelog
void live_entry(int index)
{
	// Local variables
	char local_name[248];
	char local_class[64];
	char local_capabilities[64];

	//Populate the local variables
	strcpy(local_name, dev_cache[index].name);
	strcpy(local_class, device_class(dev_cache[index].major_class, dev_cache[index].minor_class));
	strcpy(local_capabilities, device_capability(dev_cache[index].flags));

	// Let's format these a little nicer
	if (!strcmp(local_name, "VOID"))
		strcpy(local_name, "No Response");
	if (!strcmp(local_class, "VOID"))
		strcpy(local_class, "Unclassified");
	if (!strcmp(local_capabilities, "VOID"))
		strcpy(local_capabilities, "Not Reported");

	// Write out log
	fprintf(outfile,"%s,", dev_cache[index].time);
	fprintf(outfile,"%s,", dev_cache[index].addr);
	fprintf(outfile,"%s,", local_name);
	fprintf(outfile,"%s,", local_class);

	// Last field is variable
	if (config.getmanufacturer)
		fprintf(outfile,"%s", mac_get_vendor(dev_cache[index].priv_addr));
	else
		fprintf(outfile,"%s", local_capabilities);

	fprintf(outfile,"\n");
}
示例#3
0
int
ext2fs_mountroot(void)
{
	extern struct vnode *rootvp;
	struct m_ext2fs *fs;
	struct mount *mp;
	struct ufsmount *ump;
	int error;

	if (device_class(root_device) != DV_DISK)
		return ENODEV;

	if ((error = vfs_rootmountalloc(MOUNT_EXT2FS, "root_device", &mp))) {
		vrele(rootvp);
		return error;
	}

	if ((error = ext2fs_mountfs(rootvp, mp)) != 0) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		return error;
	}
	mountlist_append(mp);
	ump = VFSTOUFS(mp);
	fs = ump->um_e2fs;
	ext2fs_sb_setmountinfo(fs, mp);
	(void)ext2fs_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	setrootfstime((time_t)fs->e2fs.e2fs_wtime);
	return 0;
}
示例#4
0
int
cd9660_mountroot(void)
{
	struct mount *mp;
	struct lwp *l = curlwp;
	int error;
	struct iso_args args;

	if (device_class(root_device) != DV_DISK)
		return (ENODEV);

	if ((error = vfs_rootmountalloc(MOUNT_CD9660, "root_device", &mp))
			!= 0) {
		vrele(rootvp);
		return (error);
	}

	args.flags = ISOFSMNT_ROOT;
	if ((error = iso_mountfs(rootvp, mp, l, &args)) != 0) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		return (error);
	}
	mountlist_append(mp);
	(void)cd9660_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	return (0);
}
示例#5
0
文件: input.cpp 项目: goofwear/mame
input_code input_manager::poll_keyboard_switches()
{
	// iterate over devices within each class
	input_class &keyboard_class = device_class(DEVICE_CLASS_KEYBOARD);
	for (int devnum = 0; devnum < keyboard_class.maxindex(); devnum++)
	{
		// fetch the device; ignore if nullptr
		input_device *device = keyboard_class.device(devnum);
		if (device == nullptr)
			continue;

		// iterate over items within each device
		for (input_item_id itemid = ITEM_ID_FIRST_VALID; itemid <= device->maxitem(); ++itemid)
		{
			input_device_item *item = device->item(itemid);
			if (item != nullptr && item->itemclass() == ITEM_CLASS_SWITCH)
			{
				input_code code = item->code();
				if (code_pressed_once(code))
					return code;
			}
		}
	}

	// if nothing, return an invalid code
	return INPUT_CODE_INVALID;
}
void
device_register(device_t dev, void *aux)
{

	if ((booted_device == NULL) && (netboot == 1))
		if (device_class(dev) == DV_IFNET)
			booted_device = dev;
}
示例#7
0
static int
is_valid_disk(device_t dv)
{

	if (device_class(dv) != DV_DISK)
		return (0);
	
	return (device_is_a(dv, "dk") ||
		device_is_a(dv, "sd") ||
		device_is_a(dv, "wd") ||
		device_is_a(dv, "ld") ||
		device_is_a(dv, "ed"));
}
示例#8
0
文件: autoconf.c 项目: ryo/netbsd-src
/*
 * Choose root and swap devices.
 */
void 
cpu_rootconf(void)
{
	struct prom_n2f *nf;
	const char *devname;
	findfunc_t find;
	char promname[4];
	char partname[4];
	const char *prompath;
	int prom_ctlr, prom_unit, prom_part;

	/* Get the PROM boot path and take it apart. */
	prompath = prom_getbootpath();
	if (prompath == NULL)
		prompath = "zz(0,0,0)";
	promname[0] = *(prompath++);
	promname[1] = *(prompath++);
	promname[2] = '\0';
	prom_ctlr = prom_unit = prom_part = 0;
	if (*prompath == '(' &&
	    *(prompath = str2hex(++prompath, &prom_ctlr)) == ',' &&
	    *(prompath = str2hex(++prompath, &prom_unit)) == ',') 
		(void)str2hex(++prompath, &prom_part);

	/* Default to "unknown" */
	booted_device = NULL;
	booted_partition = 0;
	devname = "<unknown>";
	partname[0] = '\0';
	find = NULL;

	/* Do we know anything about the PROM boot device? */
	for (nf = prom_dev_table; nf->func; nf++)
		if (!strcmp(nf->name, promname)) {
			find = nf->func;
			break;
		}
	if (find)
		booted_device = (*find)(promname, prom_ctlr, prom_unit);
	if (booted_device) {
		devname = device_xname(booted_device);
		if (device_class(booted_device) == DV_DISK) {
			booted_partition = prom_part & 7;
			partname[0] = 'a' + booted_partition;
			partname[1] = '\0';
		}
	}

	printf("boot device: %s%s\n", devname, partname);
	rootconf();
}
示例#9
0
void
device_register(struct device *dev, void *aux)
{

	if (booted_device != NULL)
		return;

	if (netboot == 1) {
		/* check tlp0 on netboot */
		if (device_class(dev) == DV_IFNET &&
		    device_is_a(dev, "tlp")) {
			struct pci_attach_args *pa = aux;

			if (pa->pa_bus == 0 &&
			    pa->pa_device == 7 &&
			    pa->pa_function == 0)
				booted_device = dev;
		}
	} else {
		/* check wd channel and drive */
		if (device_class(dev) == DV_DISK &&
		    device_is_a(dev, "wd")) {
			struct ata_device *adev = aux;
			int unit;

			unit = adev->adev_channel * 2 +
			    adev->adev_drv_data->drive;
			if (unit == bootunit) {
				booted_device = dev;
			}
		}
		/*
		 * XXX Match up MBR boot specification with BSD disklabel
		 *     for root?
		 */
		booted_partition = 0;
	}
}
示例#10
0
device_t
device_isa_register(device_t dev, void *aux)
{
	/*
	 * Handle network interfaces here, the attachment information is
	 * not available driver-independently later.
	 *
	 * For disks, there is nothing useful available at attach time.
	 */
	if (device_class(dev) == DV_IFNET) {
		struct btinfo_netif *bin = lookup_bootinfo(BTINFO_NETIF);
		if (bin == NULL)
			return NULL;

		/*
		 * We don't check the driver name against the device name
		 * passed by the boot ROM.  The ROM should stay usable if
		 * the driver becomes obsolete.  The physical attachment
		 * information (checked below) must be sufficient to
		 * identify the device.
		 */
		if (bin->bus == BI_BUS_ISA &&
		    device_is_a(device_parent(dev), "isa")) {
			struct isa_attach_args *iaa = aux;

			/* Compare IO base address */
			/* XXXJRT What about multiple IO addrs? */
			if (iaa->ia_nio > 0 &&
			    bin->addr.iobase == iaa->ia_io[0].ir_addr)
			    	return dev;
		}
	}
#if NACPICA > 0
#if notyet
	if (device_is_a(dev, "isa") && acpi_active) {
		if (!(AcpiGbl_FADT.BootFlags & ACPI_FADT_LEGACY_DEVICES))
			prop_dictionary_set_bool(device_properties(dev),
			    "no-legacy-devices", true);
	}
#endif
#endif /* NACPICA > 0 */
	return NULL;
}
示例#11
0
int
msdosfs_mountroot(void)
{
	struct mount *mp;
	struct lwp *l = curlwp;	/* XXX */
	int error;
	struct msdosfs_args args;

	if (device_class(root_device) != DV_DISK)
		return (ENODEV);

	if ((error = vfs_rootmountalloc(MOUNT_MSDOS, "root_device", &mp))) {
		vrele(rootvp);
		return (error);
	}

	args.flags = MSDOSFSMNT_VERSIONED;
	args.uid = 0;
	args.gid = 0;
	args.mask = 0777;
	args.version = MSDOSFSMNT_VERSION;
	args.dirmask = 0777;

	if ((error = msdosfs_mountfs(rootvp, mp, l, &args)) != 0) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		return (error);
	}

	if ((error = update_mp(mp, &args)) != 0) {
		(void)msdosfs_unmount(mp, 0);
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		vrele(rootvp);
		return (error);
	}

	mountlist_append(mp);
	(void)msdosfs_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	return (0);
}
示例#12
0
int
ext2fs_mountroot(void)
{	
//	printf("ext2fs_mountroot\n");
	extern struct vnode *rootvp;
	struct m_ext2fs *fs;
	struct mount *mp;
	struct ufsmount *ump;
	int error;

	if (device_class(root_device) != DV_DISK)
		return (ENODEV);

	if ((error = vfs_rootmountalloc(MOUNT_EXT2FS, "root_device", &mp))) {
		vrele(rootvp);
		return (error);
	}

	if ((error = ext2fs_mountfs(rootvp, mp)) != 0) {
		vfs_unbusy(mp, false, NULL);
		vfs_destroy(mp);
		return (error);
	}
	mountlist_append(mp);
	ump = VFSTOUFS(mp);
	fs = ump->um_e2fs;
	memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt));
	(void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs_fsmnt,
	    sizeof(fs->e2fs_fsmnt) - 1, 0);
	if (fs->e2fs.e2fs_rev > E2FS_REV0) {
		memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt));
		(void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs.e2fs_fsmnt,
		    sizeof(fs->e2fs.e2fs_fsmnt) - 1, 0);
	}
	(void)ext2fs_statvfs(mp, &mp->mnt_stat);
	vfs_unbusy(mp, false, NULL);
	setrootfstime((time_t)fs->e2fs.e2fs_wtime);
	return (0);
}
示例#13
0
int
#define struct
ext2fs_mountroot(struct mount *mp)
{
	struct vnode *rootvp;
#undef struct
        struct m_ext2fs *fs;
//        struct mount *mp;
        int error;
        
        DEBUG ((EFI_D_INFO, "mountroot 1\n"));
        if (device_class(root_device) != DV_DISK)
    		return (ENONDEV);
        
        DEBUG ((EFI_D_INFO, "mountroot 2\n"));
        if ((error = vfs_rootmountalloc(MOUNT_EXT2FS, "root_device", &mp))) {
    		vrele(rootvp);
                return (error);
        }
        
        DEBUG ((EFI_D_INFO, "mountroot 3\n"));
        if ((error = ext2fs_mountfs(rootvp, mp)) != 0) {
    		vfs_unbusy(mp,false,NULL);
    		vfs_destroy(mp);
                return (error);
        }

      DEBUG ((EFI_D_INFO, "mountroot 4\n"));
        fs = mp->fs;
        memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt));
        (void) copystr(mp->f_mntonname, fs->e2fs_fsmnt,
            sizeof(fs->e2fs_fsmnt) - 1, 0);
        if (fs->e2fs.e2fs_rev > E2FS_REV0) {
                memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt));
                (void) copystr(mp->f_mntonname, fs->e2fs.e2fs_fsmnt,
                    sizeof(fs->e2fs.e2fs_fsmnt) - 1, 0);
        }
        vfs_unbusy(mp, false, NULL);
        return (0);
static void
findroot(void)
{
	device_t dv;
	deviter_t di;

	if (booted_device)
		return;

	if ((booted_device == NULL) && netboot == 0) {
		for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
		    dv = deviter_next(&di)) {
			if (device_class(dv) == DV_DISK &&
			    device_is_a(dv, "wd"))
				booted_device = dv;
		}
		deviter_release(&di);
	}

	/*
	 * XXX Match up MBR boot specification with BSD disklabel for root?
	 */
	booted_partition = 0;
}
示例#15
0
static void
setbootdev(void)
{
	struct dev_data *cdd, *dd;
	int type, ctlr;

	/*
	 * Note our magic numbers for type:
	 *
	 *	0 == ct
	 *	2 == rd
	 *	4 == sd
	 *	6 == le
	 *
	 * Allare bdevsw major numbers, except for le, which
	 * is just special.
	 *
	 * We can't mount root on a tape, so we ignore those.
	 */

	/*
	 * Start with a clean slate.
	 */
	bootdev = 0;

	/*
	 * If the root device is network, we're done
	 * early.
	 */
	if (device_class(root_device) == DV_IFNET) {
		bootdev = MAKEBOOTDEV(6, 0, 0, 0, 0);
		goto out;
	}

	/*
	 * Determine device type.
	 */
	if (device_is_a(root_device, "rd"))
		type = 2;
	else if (device_is_a(root_device, "sd"))
		type = 4;
	else if (device_is_a(root_device, "md"))
		goto out;
	else {
		printf("WARNING: strange root device!\n");
		goto out;
	}

	dd = dev_data_lookup(root_device);

	/*
	 * Get parent's info.
	 */
	switch (type) {
	case 2: /* rd */
	case 4: /* sd */
		/*
		 * "rd" -> "hpibbus" -> "fhpib"
		 * "sd" -> "scsibus" -> "spc"
		 */
		for (cdd = LIST_FIRST(&dev_data_list_hpib), ctlr = 0;
		    cdd != NULL; cdd = LIST_NEXT(cdd, dd_clist), ctlr++) {
			if (cdd->dd_dev ==
			    device_parent(device_parent(root_device))) {
				/*
				 * Found it!
				 */
				bootdev = MAKEBOOTDEV(type,
				    ctlr, dd->dd_slave, dd->dd_punit,
				    DISKPART(rootdev));
				break;
			}
		}
		break;
	}

 out:
	/* Don't need this anymore. */
	for (dd = LIST_FIRST(&dev_data_list); dd != NULL; ) {
		cdd = dd;
		dd = LIST_NEXT(dd, dd_list);
		free(cdd, M_DEVBUF);
	}
}
示例#16
0
static void
findbootdev(void)
{
	int type, ctlr, slave, punit, part;
	int scsiboot, hpibboot, netboot;
	struct dev_data *dd;

	booted_device = NULL;
	booted_partition = 0;

	if ((bootdev & B_MAGICMASK) != B_DEVMAGIC)
		return;

	type  = B_TYPE(bootdev);
	ctlr  = B_ADAPTOR(bootdev);
	slave = B_CONTROLLER(bootdev);
	punit = B_UNIT(bootdev);
	part  = B_PARTITION(bootdev);

	scsiboot = (type == 4);			/* sd major */
	hpibboot = (type == 0 || type == 2);	/* ct/rd major */
	netboot  = (type == 6);			/* le - special */

	/*
	 * Check for network boot first, since it's a little
	 * different.  The BOOTROM/boot program can only boot
	 * off of the first (lowest select code) ethernet
	 * device.  device_register() knows this and only
	 * registers one DV_IFNET.  This is a safe assumption
	 * since the code that finds devices on the DIO bus
	 * always starts at scode 0 and works its way up.
	 */
	if (netboot) {
		for (dd = LIST_FIRST(&dev_data_list); dd != NULL;
		    dd = LIST_NEXT(dd, dd_list)) {
			if (device_class(dd->dd_dev) == DV_IFNET) {
				/*
				 * Found it!
				 */
				booted_device = dd->dd_dev;
				break;
			}
		}
		return;
	}

	/*
	 * Check for HP-IB boots next.
	 */
	if (hpibboot) {
		findbootdev_slave(&dev_data_list_hpib, ctlr,
		    slave, punit);
		if (booted_device == NULL)
			return;

		/*
		 * Sanity check.
		 */
		if ((type == 0 && !device_is_a(booted_device, "ct")) ||
		    (type == 2 && !device_is_a(booted_device, "rd"))) {
			printf("WARNING: boot device/type mismatch!\n");
			printf("device = %s, type = %d\n",
			    booted_device->dv_xname, type);
			booted_device = NULL;
		}
		goto out;
	}

	/*
	 * Check for SCSI boots last.
	 */
	if (scsiboot) {
		findbootdev_slave(&dev_data_list_scsi, ctlr,
		     slave, punit);
		if (booted_device == NULL)
			return;

		/*
		 * Sanity check.
		 */
		if ((type == 4 && !device_is_a(booted_device, "sd"))) {
			printf("WARNING: boot device/type mismatch!\n");
			printf("device = %s, type = %d\n",
			    booted_device->dv_xname, type);
			booted_device = NULL;
		}
		goto out;
	}

	/* Oof! */
	printf("WARNING: UNKNOWN BOOT DEVICE TYPE = %d\n", type);

 out:
	if (booted_device != NULL)
		booted_partition = part;
}
示例#17
0
/*
 * Register a device.  We're passed the device and the arguments
 * used to attach it.  This is used to find the boot device.
 */
void
device_register(struct device *dev, void *aux)
{
	struct dev_data *dd;
	static int seen_netdevice = 0;

	/*
	 * Allocate a dev_data structure and fill it in.
	 * This means making some tests twice, but we don't
	 * care; this doesn't really have to be fast.
	 *
	 * Note that we only really care about devices that
	 * we can mount as root.
	 */

	dd = malloc(sizeof(struct dev_data), M_DEVBUF, M_NOWAIT | M_ZERO);
	if (dd == NULL)
		panic("device_register: can't allocate dev_data");

	dd->dd_dev = dev;

	/*
	 * BOOTROM and boot program can really only understand
	 * using the lowest select code network interface,
	 * so we ignore all but the first.
	 */
	if (device_class(dev) == DV_IFNET && seen_netdevice == 0) {
		struct dio_attach_args *da = aux;

		seen_netdevice = 1;
		dd->dd_scode = da->da_scode;
		goto linkup;
	}

	if (device_is_a(dev, "fhpib") ||
	    device_is_a(dev, "nhpib") ||
	    device_is_a(dev, "spc")) {
		struct dio_attach_args *da = aux;

		dd->dd_scode = da->da_scode;
		goto linkup;
	}

	if (device_is_a(dev, "rd")) {
		struct hpibbus_attach_args *ha = aux;

		dd->dd_slave = ha->ha_slave;
		dd->dd_punit = ha->ha_punit;
		goto linkup;
	}

	if (device_is_a(dev, "sd")) {
		struct scsipibus_attach_args *sa = aux;

		dd->dd_slave = sa->sa_periph->periph_target;
		dd->dd_punit = sa->sa_periph->periph_lun;
		goto linkup;
	}

	/*
	 * Didn't need the dev_data.
	 */
	free(dd, M_DEVBUF);
	return;

 linkup:
	LIST_INSERT_HEAD(&dev_data_list, dd, dd_list);

	if (device_is_a(dev, "fhpib") ||
	    device_is_a(dev, "nhpib")) {
		dev_data_insert(dd, &dev_data_list_hpib);
		return;
	}

	if (device_is_a(dev, "spc")) {
		dev_data_insert(dd, &dev_data_list_scsi);
		return;
	}
}
示例#18
0
void
cpu_rootconf(void)
{
	struct dev_data *dd;
	struct device *dv;
	struct vfsops *vops;

	/*
	 * Find boot device.
	 */
	if ((bootdev & B_MAGICMASK) != B_DEVMAGIC) {
		printf("WARNING: boot program didn't supply boot device.\n");
		printf("Please update your boot program.\n");
	} else {
		findbootdev();
		if (booted_device == NULL) {
			printf("WARNING: can't find match for bootdev:\n");
			printf(
		    "type = %d, ctlr = %d, slave = %d, punit = %d, part = %d\n",
			    B_TYPE(bootdev), B_ADAPTOR(bootdev),
			    B_CONTROLLER(bootdev), B_UNIT(bootdev),
			    B_PARTITION(bootdev));
			bootdev = 0;		/* invalidate bootdev */
		} else {
			printf("boot device: %s\n", booted_device->dv_xname);
		}
	}

	dv = booted_device;

	/*
	 * If wild carded root device and wired down NFS root file system,
	 * pick the network interface device to use.
	 */
	if (rootspec == NULL) {
		vops = vfs_getopsbyname("nfs");
		if (vops != NULL && vops->vfs_mountroot == mountroot) {
			for (dd = LIST_FIRST(&dev_data_list);
			    dd != NULL; dd = LIST_NEXT(dd, dd_list)) {
				if (device_class(dd->dd_dev) == DV_IFNET) {
					/* Got it! */
					dv = dd->dd_dev;
					break;
				}
			}
			if (dd == NULL) {
				printf("no network interface for NFS root");
				dv = NULL;
			}
		}
	}

	/*
	 * If bootdev is bogus, ask the user anyhow.
	 */
	if (bootdev == 0)
		boothowto |= RB_ASKNAME;

	/*
	 * If we booted from tape, ask the user.
	 */
	if (booted_device != NULL && device_class(booted_device) == DV_TAPE)
		boothowto |= RB_ASKNAME;

	setroot(dv, booted_partition);

	/*
	 * Set bootdev based on what we found as the root.
	 * This is given to the boot program when we reboot.
	 */
	setbootdev();

}
示例#19
0
void
device_register(device_t dev, void *aux)
{
#if NPCI > 0
	static bool found_console = false;
	struct pci_attach_args *paa = aux;
#endif

	/*
	 * Handle network interfaces here, the attachment information is
	 * not available driver-independently later.
	 *
	 * For disks, there is nothing useful available at attach time.
	 */
	if (device_class(dev) == DV_IFNET) {
		struct btinfo_netif *bin = lookup_bootinfo(BTINFO_NETIF);
		if (bin == NULL)
			return;

		/*
		 * We don't check the driver name against the device name
		 * passed by the boot ROM.  The ROM should stay usable if
		 * the driver becomes obsolete.  The physical attachment
		 * information (checked below) must be sufficient to
		 * idenfity the device.
		 */
		if (bin->bus == BI_BUS_ISA &&
		    device_is_a(device_parent(dev), "isa")) {
			struct isa_attach_args *iaa = aux;

			/* Compare IO base address */
			/* XXXJRT What about multiple IO addrs? */
			if (iaa->ia_nio > 0 &&
			    bin->addr.iobase == iaa->ia_io[0].ir_addr)
			    	goto found;
		}
#if NPCI > 0
		if (bin->bus == BI_BUS_PCI &&
		    device_is_a(device_parent(dev), "pci")) {
			int b, d, f;

			/*
			 * Calculate BIOS representation of:
			 *
			 *	<bus,device,function>
			 *
			 * and compare.
			 */
			pci_decompose_tag(paa->pa_pc, paa->pa_tag, &b, &d, &f);
			if (bin->addr.tag == ((b << 8) | (d << 3) | f))
				goto found;
		}
#endif /* NPCI > 0 */
	}
#if NISA > 0 && NACPICA > 0
#if notyet
	if (device_is_a(dev, "isa") && acpi_active) {
		if (!(AcpiGbl_FADT.BootFlags & ACPI_FADT_LEGACY_DEVICES))
			prop_dictionary_set_bool(device_properties(dev),
			    "no-legacy-devices", true);
	}
#endif
#endif /* NISA > 0 && NACPICA > 0 */
#if NPCI > 0
	if (device_parent(dev) && device_is_a(device_parent(dev), "pci") &&
	    found_console == false) {
		struct btinfo_framebuffer *fbinfo;
		struct pci_attach_args *pa = aux;
		prop_dictionary_t dict;
#if NACPICA > 0
		struct genfb_parameter_callback *gpc;
		int b, d, f;
#endif

		if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY) {
#if NWSDISPLAY > 0 && NGENFB > 0
			extern struct vcons_screen x86_genfb_console_screen;
			struct rasops_info *ri;

			ri = &x86_genfb_console_screen.scr_ri;
#endif

			fbinfo = lookup_bootinfo(BTINFO_FRAMEBUFFER);
			dict = device_properties(dev);
			/*
			 * framebuffer drivers other than genfb can work
			 * without the address property
			 */
			if (fbinfo != NULL) {
				if (fbinfo->physaddr != 0) {
				prop_dictionary_set_uint32(dict, "width",
				    fbinfo->width);
				prop_dictionary_set_uint32(dict, "height",
				    fbinfo->height);
				prop_dictionary_set_uint8(dict, "depth",
				    fbinfo->depth);
				prop_dictionary_set_uint16(dict, "linebytes",
				    fbinfo->stride);

				prop_dictionary_set_uint64(dict, "address",
				    fbinfo->physaddr);
#if NWSDISPLAY > 0 && NGENFB > 0
				if (ri->ri_bits != NULL) {
					prop_dictionary_set_uint64(dict,
					    "virtual_address",
					    (vaddr_t)ri->ri_bits);
				}
#endif
				}
#if notyet
				prop_dictionary_set_bool(dict, "splash",
				    fbinfo->flags & BI_FB_SPLASH ?
				     true : false);
#endif
				if (fbinfo->depth == 8) {
					gfb_cb.gcc_cookie = NULL;
					gfb_cb.gcc_set_mapreg = 
					    x86_genfb_set_mapreg;
					prop_dictionary_set_uint64(dict,
					    "cmap_callback",
					    (uint64_t)(uintptr_t)&gfb_cb);
				}
				if (fbinfo->physaddr != 0) {
					mode_cb.gmc_setmode = x86_genfb_setmode;
					prop_dictionary_set_uint64(dict,
					    "mode_callback",
					    (uint64_t)(uintptr_t)&mode_cb);
				}

#if NWSDISPLAY > 0 && NGENFB > 0
				if (device_is_a(dev, "genfb")) {
					x86_genfb_set_console_dev(dev);
#ifdef DDB
					db_trap_callback =
					    x86_genfb_ddb_trap_callback;
#endif
				}
#endif
			}
			prop_dictionary_set_bool(dict, "is_console", true);
			prop_dictionary_set_bool(dict, "clear-screen", false);
#if NWSDISPLAY > 0 && NGENFB > 0
			prop_dictionary_set_uint16(dict, "cursor-row",
			    x86_genfb_console_screen.scr_ri.ri_crow);
#endif
#if notyet
			prop_dictionary_set_bool(dict, "splash",
			    fbinfo->flags & BI_FB_SPLASH ? true : false);
#endif
			pmf_cb.gpc_suspend = x86_genfb_suspend;
			pmf_cb.gpc_resume = x86_genfb_resume;
			prop_dictionary_set_uint64(dict,
			    "pmf_callback", (uint64_t)(uintptr_t)&pmf_cb);
#if NACPICA > 0
			pci_decompose_tag(paa->pa_pc, paa->pa_tag, &b, &d, &f);
			gpc = acpidisp_md_out_find(b, d, f);
			if (gpc != NULL)
				prop_dictionary_set_uint64(dict,
				    "brightness_callback", (uint64_t)(vaddr_t)gpc);
#endif
#ifdef VGA_POST
			vga_posth = vga_post_init(pa->pa_bus, pa->pa_device,
			    pa->pa_function);
#endif
			found_console = true;
			return;
		}
	}
#endif
	return;

 found:
	if (booted_device) {
		/* XXX should be a panic() */
		printf("WARNING: double match for boot device (%s, %s)\n",
		    device_xname(booted_device), device_xname(dev));
		return;
	}
	booted_device = dev;
}
示例#20
0
/*
 * Attempt to find the device from which we were booted.  If we can do so,
 * and not instructed not to do so, change rootdev to correspond to the
 * load device.
 */
static void
findroot(void)
{
	struct btinfo_rootdevice *biv;
	struct btinfo_bootdisk *bid;
	struct btinfo_bootwedge *biw;
	struct btinfo_biosgeom *big;
	device_t dv;
	deviter_t di;

	if (booted_device)
		return;
	
	if (lookup_bootinfo(BTINFO_NETIF) != NULL) {
		/*
		 * We got netboot interface information, but device_register()
		 * failed to match it to a configured device.  Boot disk
		 * information cannot be present at the same time, so give
		 * up.
		 */
		printf("%s: netboot interface not found.\n", __func__);
		return;
	}

	if ((biv = lookup_bootinfo(BTINFO_ROOTDEVICE)) != NULL) {
		for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
		     dv != NULL;
		     dv = deviter_next(&di)) {
			cfdata_t cd;
			size_t len;

			if (device_class(dv) != DV_DISK)
				continue;

			cd = device_cfdata(dv);
			len = strlen(cd->cf_name);

			if (strncmp(cd->cf_name, biv->devname, len) == 0 &&
			    biv->devname[len] - '0' == device_unit(dv)) {
				booted_device = dv;
				booted_partition = biv->devname[len + 1] - 'a';
				booted_nblks = 0;
				break;
			}
		}
		DPRINTF(("%s: BTINFO_ROOTDEVICE %s\n", __func__,
		    booted_device ? device_xname(booted_device) : "not found"));
		deviter_release(&di);
		if (dv != NULL)
			return;
	}

	bid = lookup_bootinfo(BTINFO_BOOTDISK);
	biw = lookup_bootinfo(BTINFO_BOOTWEDGE);

	if (biw != NULL) {
		/*
		 * Scan all disk devices for ones that match the passed data.
		 * Don't break if one is found, to get possible multiple
		 * matches - for problem tracking.  Use the first match anyway
		 * because lower devices numbers are more likely to be the
		 * boot device.
		 */
		for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
		     dv != NULL;
		     dv = deviter_next(&di)) {
			if (is_valid_disk(dv)) {
				/*
				 * Don't trust BIOS device numbers, try
				 * to match the information passed by the
				 * boot loader instead.
				 */
				if ((biw->biosdev & 0x80) == 0 ||
				    match_bootwedge(dv, biw) == 0)
				    	continue;
				goto bootwedge_found;
			}

			continue;
 bootwedge_found:
			if (booted_device) {
				dmatch(__func__, dv);
				continue;
			}
			booted_device = dv;
			booted_partition = bid != NULL ? bid->partition : 0;
			booted_nblks = biw->nblks;
			booted_startblk = biw->startblk;
		}
		deviter_release(&di);

		DPRINTF(("%s: BTINFO_BOOTWEDGE %s\n", __func__,
		    booted_device ? device_xname(booted_device) : "not found"));
		if (booted_nblks)
			return;
	}

	if (bid != NULL) {
		/*
		 * Scan all disk devices for ones that match the passed data.
		 * Don't break if one is found, to get possible multiple
		 * matches - for problem tracking.  Use the first match anyway
		 * because lower device numbers are more likely to be the
		 * boot device.
		 */
		for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
		     dv != NULL;
		     dv = deviter_next(&di)) {

			if (device_is_a(dv, "fd") &&
			    device_class(dv) == DV_DISK) {
				/*
				 * Assume the configured unit number matches
				 * the BIOS device number.  (This is the old
				 * behavior.)  Needs some ideas how to handle
				 * the BIOS's "swap floppy drive" options.
				 */
				/* XXX device_unit() abuse */
				if ((bid->biosdev & 0x80) != 0 ||
				    device_unit(dv) != bid->biosdev)
				    	continue;
				goto bootdisk_found;
			}

			if (is_valid_disk(dv)) {
				/*
				 * Don't trust BIOS device numbers, try
				 * to match the information passed by the
				 * boot loader instead.
				 */
				if ((bid->biosdev & 0x80) == 0 ||
				    match_bootdisk(dv, bid) == 0)
				    	continue;
				goto bootdisk_found;
			}

			continue;
 bootdisk_found:
			if (booted_device) {
				dmatch(__func__, dv);
				continue;
			}
			booted_device = dv;
			booted_partition = bid->partition;
			booted_nblks = 0;
		}
		deviter_release(&di);

		DPRINTF(("%s: BTINFO_BOOTDISK %s\n", __func__,
		    booted_device ? device_xname(booted_device) : "not found"));
		if (booted_device)
			return;

		/*
		 * No booted device found; check CD-ROM boot at last.
		 *
		 * Our bootloader assumes CD-ROM boot if biosdev is larger
		 * or equal than the number of hard drives recognized by the
		 * BIOS. The number of drives can be found in BTINFO_BIOSGEOM
		 * here. For example, if we have wd0, wd1, and cd0:
		 *
		 *	big->num = 2 (for wd0 and wd1)
		 *	bid->biosdev = 0x80 (wd0)
		 *	bid->biosdev = 0x81 (wd1)
		 *	bid->biosdev = 0x82 (cd0)
		 *
		 * See src/sys/arch/i386/stand/boot/devopen.c and
		 * src/sys/arch/i386/stand/lib/bootinfo_biosgeom.c .
		 */
		if ((big = lookup_bootinfo(BTINFO_BIOSGEOM)) != NULL &&
		    bid->biosdev >= 0x80 + big->num) {
			/*
			 * XXX
			 * There is no proper way to detect which unit is
			 * recognized as a bootable CD-ROM drive by the BIOS.
			 * Assume the first unit is the one.
			 */
			for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
			     dv != NULL;
			     dv = deviter_next(&di)) {
				if (device_class(dv) == DV_DISK &&
				    device_is_a(dv, "cd")) {
					booted_device = dv;
					booted_partition = 0;
					booted_nblks = 0;
					break;
				}
			}
			deviter_release(&di);
			DPRINTF(("%s: BTINFO_BIOSGEOM %s\n", __func__,
			    booted_device ? device_xname(booted_device) :
			    "not found"));
		}
	}
}
示例#21
0
文件: bluelog.c 项目: naranek/Bluelog
int main(int argc, char *argv[])
{
	// Handle signals
	signal(SIGINT,shut_down);
	signal(SIGHUP,shut_down);
	signal(SIGTERM,shut_down);
	signal(SIGQUIT,shut_down);

	// HCI device number, MAC struct
	int device = 0;
	bdaddr_t bdaddr;
	bacpy(&bdaddr, BDADDR_ANY);

	// Time to scan. Scan time is roughly 1.28 seconds * scan_window
	// Originally this was always 8, now we adjust based on device:
	#ifdef OPENWRT
	int scan_window = 8;
	#elif PWNPLUG
	int scan_window = 5;
	#else
	int scan_window = 3;
	#endif

	// Maximum number of devices per scan
	int max_results = 255;
	int num_results;

	// Device cache and index
	int cache_index = 0;

	// HCI cache setting
	int flags = IREQ_CACHE_FLUSH;

	// Strings to hold MAC and name
	char addr[19] = {0};
	char addr_buff[19] = {0};

	// String for time
	char cur_time[20];

	// Process ID read from PID file
	int ext_pid;

	// Pointers to filenames
	char *infofilename = LIVE_INF;

	// Change default filename based on date
	char OUT_FILE[1000] = OUT_PATH;
	strncat(OUT_FILE, file_timestamp(),sizeof(OUT_FILE)-strlen(OUT_FILE)-1);
	char *outfilename = OUT_FILE;

	// Mode to open output file in
	char *filemode = "a+";

	// Output buffer
	char outbuffer[500];

	// Buffer for data from the second loop
	char exitbuffer[500];

	// Misc Variables
	int i, ri, opt;

	// Record numbner of BlueZ errors
	int error_count = 0;

	// Current epoch time
	long long int epoch;

	// Kernel version info
	struct utsname sysinfo;
	uname(&sysinfo);

	while ((opt=getopt_long(argc,argv,"+o:i:r:a:w:vxctghldbfenksmq", main_options, NULL)) != EOF)
	{
		switch (opt)
		{
		case 'i':
			if (!strncasecmp(optarg, "hci", 3))
				hci_devba(atoi(optarg + 3), &bdaddr);
			else
				str2ba(optarg, &bdaddr);
			break;
		case 'o':
			outfilename = strdup(optarg);
			break;
		case 'r':
			config.retry_count = atoi(optarg);
			break;
		case 'a':
			config.amnesia = atoi(optarg);
			break;
		case 'w':
			config.scan_window = round((atoi(optarg) / 1.28));
			break;
		case 'c':
			config.showclass = 1;
			break;
		case 'e':
			config.encode = 1;
			break;
		case 'f':
			config.friendlyclass = 1;
			break;
		case 'v':
			config.verbose = 1;
			break;
		case 'g':
			config.status = 1;
			break;
		case 't':
			config.showtime = 1;
			break;
		case 's':
			config.syslogonly = 1;
			break;
		case 'x':
			config.obfuscate = 1;
			break;
		case 'q':
			config.quiet = 1;
			break;
		case 'l':
			if(!LIVEMODE)
			{
				printf("Live mode has been disabled in this build. See documentation.\n");
				exit(0);
			}
			else
				config.bluelive = 1;
			break;
		case 'b':
			config.bluepropro = 1;
			break;
		case 'd':
			config.daemon = 1;
			break;
		case 'n':
			config.getname = 1;
			break;
		case 'm':
			if(!OUILOOKUP)
			{
				printf("Manufacturer lookups have been disabled in this build. See documentation.\n");
				exit(0);
			}
			else
				config.getmanufacturer = 1;
			break;
		case 'h':
			help();
			exit(0);
		case 'k':
			// Read PID from file into variable
			ext_pid = read_pid();
			if (ext_pid != 0)
			{
				printf("Killing Bluelog process with PID %i...",ext_pid);
				if(kill(ext_pid,15) != 0)
				{
					printf("ERROR!\n");
					printf("Unable to kill Bluelog process. Check permissions.\n");
					exit(1);
				}
				else
					printf("OK.\n");

				// Delete PID file
				unlink(PID_FILE);
			}
			else
				printf("No running Bluelog process found.\n");

			exit(0);
		default:
			printf("Unknown option. Use -h for help, or see README.\n");
			exit(1);
		}
	}

	// See if there is already a process running
	if (read_pid() != 0)
	{
		printf("Another instance of Bluelog is already running!\n");
		printf("Use the -k option to kill a running Bluelog process.\n");
		exit(1);
	}

	// Load config from file if no options given on command line
	if(cfg_exists() && argc == 1)
	{
		if (cfg_read() != 0)
		{
			printf("Error opening config file!\n");
			exit(1);
		}
		// Put interface into BT struct
		hci_devba(config.hci_device, &bdaddr);
	}

	// Perform sanity checks on varibles
	cfg_check();

	// Setup libmackerel
	mac_init();

	// Boilerplate
	if (!config.quiet)
	{
		printf("%s (v%s%s) by MS3FGX\n", APPNAME, VERSION, VER_MOD);
		#if defined OPENWRT || PWNPLUG
			printf("----");
		#endif
		printf("---------------------------\n");
	}

	// Show notification we loaded config from file
	if(cfg_exists() && argc == 1 && !config.quiet)
		printf("Config loaded from: %s\n", CFG_FILE);

	// Init Hardware
	ba2str(&bdaddr, config.addr);
	if (!strcmp(config.addr, "00:00:00:00:00:00"))
	{
		if (!config.quiet)
			printf("Autodetecting device...");
		device = hci_get_route(NULL);
		// Put autodetected device MAC into addr
		hci_devba(device, &bdaddr);
		ba2str(&bdaddr, config.addr);
	}
	else
	{
		if (!config.quiet)
			printf("Initializing device...");
		device = hci_devid(config.addr);
	}

	// Open device and catch errors
	config.bt_socket = hci_open_dev(device);
	if (device < 0 || config.bt_socket < 0)
	{
		// Failed to open device, that can't be good
		printf("\n");
		printf("Error initializing Bluetooth device!\n");
		exit(1);
	}

	// If we get here the device should be online.
	if (!config.quiet)
		printf("OK\n");

	// Status message for BPP
	if (!config.quiet)
		if (config.bluepropro)
			printf("Output formatted for BlueProPro.\n"
				   "More Info: www.hackfromacave.com\n");

	// Open socket
	if (config.udponly)
		open_udp_socket();

	// Open output file, unless in networking mode
	if (!config.syslogonly && !config.udponly)
	{
		if (config.bluelive)
		{
			// Change location of output file
			outfilename = LIVE_OUT;
			filemode = "w";
			if (!config.quiet)
				printf("Starting Bluelog Live...\n");
		}
		if (!config.quiet)
			printf("Opening output file: %s...", outfilename);
		if ((outfile = fopen(outfilename, filemode)) == NULL)
		{
			printf("\n");
			printf("Error opening output file!\n");
			exit(1);
		}
		if (!config.quiet)
			printf("OK\n");
	}
	else
		if (!config.quiet)
			printf("Network mode enabled, not creating log file.\n");

	// Open status file
	if (config.bluelive)
	{
		if (!config.quiet)
			printf("Opening info file: %s...", infofilename);
		if ((infofile = fopen(infofilename,"w")) == NULL)
		{
			printf("\n");
			printf("Error opening info file!\n");
			exit(1);
		}
		if (!config.quiet)
			printf("OK\n");
	}

	// Write PID file
	if (!config.daemon)
		write_pid(getpid());

	// Get and print time to console and file
	strcpy(cur_time, get_localtime());

	if (!config.daemon)
		printf("Scan started at [%s] on %s\n", cur_time, config.addr);

	if (config.showtime && (outfile != NULL))
	{
		fprintf(outfile,"[%s] Scan started on %s\n", cur_time, config.addr);
		// Make sure this gets written out
		fflush(outfile);
	}

	// Write info file for Bluelog Live
	if (config.bluelive)
	{
		fprintf(infofile,"<div class=\"sideitem\">%s Version: %s%s</div>\n", APPNAME, VERSION, VER_MOD);
		fprintf(infofile,"<div class=\"sideitem\">Device: %s</div>\n", config.addr);
		fprintf(infofile,"<div class=\"sideitem\">Started: %s</div>\n", cur_time);

		// Think we are done with you now
		fclose(infofile);
	}

	// Log success to this point
	syslog(LOG_INFO,"Init OK!");

	// Daemon switch
	if (config.daemon)
		daemonize();
	else
		if (!config.quiet)
			#if defined PWNPAD
			printf("Close this window to end scan.\n");
			#else
			printf("Hit Ctrl+C to end scan.\n");
			#endif

	// Init result struct
	results = (inquiry_info*)malloc(max_results * sizeof(inquiry_info));

	// Start scan, be careful with this infinite loop...
	for(;;)
	{
		// Flush results buffer
		memset(results, '\0', max_results * sizeof(inquiry_info));

		// Scan and return number of results
		num_results = hci_inquiry(device, scan_window, max_results, NULL, &results, flags);

		// A negative number here means an error during scan
		if(num_results < 0)
		{
			// Increment error count
			error_count++;

			// Ignore occasional errors on Pwn Plug and OpenWRT
			#if !defined PWNPLUG || OPENWRT
			// All other platforms, print error and bail out
			syslog(LOG_ERR,"Received error from BlueZ!");
			printf("Scan failed!\n");
			// Check for kernel 3.0.x
			if (!strncmp("3.0.",sysinfo.release,4))
			{
				printf("\n");
				printf("-----------------------------------------------------\n");
				printf("Device scanning failed, and you are running a 3.0.x\n");
				printf("Linux kernel. This failure is probably due to the\n");
				printf("following kernel bug:\n");
				printf("\n");
				printf("http://marc.info/?l=linux-kernel&m=131629118406044\n");
				printf("\n");
				printf("You will need to upgrade your kernel to at least the\n");
				printf("the 3.1 series to continue.\n");
				printf("-----------------------------------------------------\n");

			}
			shut_down(1);
			#else
			// Exit on back to back errors
			if (error_count > 5)
			{
				printf("Scan failed!\n");
				syslog(LOG_ERR,"BlueZ not responding, unrecoverable!");
				shut_down(1);
			}

			// Otherwise, throttle back a bit, might help
			sleep(1);
			#endif
		}
		else
		{
			// Clear error counter
			error_count = 0;
		}

		// Check if we need to reset device cache
		if ((cache_index + num_results) >= MAX_DEV)
		{
			syslog(LOG_INFO,"Resetting device cache...");
			memset(dev_cache, 0, sizeof(dev_cache));
			cache_index = 0;
		}



		// Loop through results
		for (i = 0; i < num_results; i++)
		{
			// Return current MAC from struct
			ba2str(&(results+i)->bdaddr, addr);

			// Compare to device cache
			for (ri = 0; ri <= cache_index; ri++)
			{
				// Determine if device is already logged
				if (strcmp (addr, dev_cache[ri].priv_addr) == 0)
				{
					// This device has been seen before

					// Increment seen count, update printed time
					dev_cache[ri].seen++;
					strcpy(dev_cache[ri].time, get_localtime());
					dev_cache[ri].missing_count = 0;

					// If we don't have a name, query again
					if ((dev_cache[ri].print == 3) && (dev_cache[ri].seen > config.retry_count))
					{
						syslog(LOG_INFO,"Unable to find name for %s!", addr);
						dev_cache[ri].print = 1;
					}
					else if ((dev_cache[ri].print == 3) && (dev_cache[ri].seen < config.retry_count))
					{
						// Query name
						strcpy(dev_cache[ri].name, namequery(&(results+i)->bdaddr));

						// Did we get one?
						if (strcmp (dev_cache[ri].name, "VOID") != 0)
						{
							syslog(LOG_INFO,"Name retry for %s successful!", addr);
							// Force print
							dev_cache[ri].print = 1;
						}
						else
							syslog(LOG_INFO,"Name retry %i for %s failed!",dev_cache[ri].seen, addr);
					}

					// Amnesia mode
					if (config.amnesia >= 0)
					{
						// Find current epoch time
						epoch = time(NULL);
						if ((epoch - dev_cache[ri].epoch) >= (config.amnesia * 60))
						{
							// Update epoch time
							dev_cache[ri].epoch = epoch;
							// Set device to print
							dev_cache[ri].print = 1;
						}
					}

					// This device is seen before, but has been away
					if (strcmp (dev_cache[ri].status, "gone") == 0)
					{
						dev_cache[ri].print = 1;
						strcpy(dev_cache[ri].status, "returned");
					}

					// Unless we need to get printed, move to next result
					if (dev_cache[ri].print != 1)
						break;
				}
				else if (strcmp (dev_cache[ri].addr, "") == 0)
				{
					// Write new device MAC (visible and internal use)
					strcpy(dev_cache[ri].addr, addr);
					strcpy(dev_cache[ri].priv_addr, addr);

					// Query for name
					if (config.getname)
						strcpy(dev_cache[ri].name, namequery(&(results+i)->bdaddr));
					else
						strcpy(dev_cache[ri].name, "IGNORED");

					// Get time found
					strcpy(dev_cache[ri].time, get_localtime());
					dev_cache[ri].epoch = time(NULL);

					// Class info
					dev_cache[ri].flags = (results+i)->dev_class[2];
					dev_cache[ri].major_class = (results+i)->dev_class[1];
					dev_cache[ri].minor_class = (results+i)->dev_class[0];

					// Init misc variables
					dev_cache[ri].seen = 1;
					dev_cache[ri].missing_count = 0;
					strcpy(dev_cache[ri].status, "new");

					// Increment index
					cache_index++;

					// If we have a device name, get printed
					if (strcmp (dev_cache[ri].name, "VOID") != 0)
						dev_cache[ri].print = 1;
					else
					{
						// Found with no name.
						// Print message to syslog, prevent printing, and move on
						syslog(LOG_INFO,"Device %s discovered with no name, will retry", dev_cache[ri].addr);
						dev_cache[ri].print = 3;
						break;
					}
				}

				// Ready to print?
				if (dev_cache[ri].print == 1)
				{
					// Encode MAC
					if (config.encode || config.obfuscate)
					{
						// Clear buffer
						memset(addr_buff, '\0', sizeof(addr_buff));

						if (config.obfuscate)
							strcpy(addr_buff, mac_obfuscate(dev_cache[ri].priv_addr));

						if (config.encode)
							strcpy(addr_buff, mac_encode(dev_cache[ri].priv_addr));

						// Copy to cache
						strcpy(dev_cache[ri].addr, addr_buff);
					}

					// Print everything to console if verbose is on, optionally friendly class info
					if (config.verbose)
					{
						if (config.friendlyclass)
						{
							printf("[%s] %s,%s,%s,(%s) - %s\n",\
								dev_cache[ri].time, dev_cache[ri].addr,\
								dev_cache[ri].name, device_class(dev_cache[ri].major_class,\
								dev_cache[ri].minor_class), device_capability(dev_cache[ri].flags), dev_cache[ri].status);
						}
						else
						{
							printf("[%s] %s,%s,0x%02x%02x%02x - %s\n",\
								dev_cache[ri].time, dev_cache[ri].addr,\
								dev_cache[ri].name, dev_cache[ri].flags,\
								dev_cache[ri].major_class, dev_cache[ri].minor_class, dev_cache[ri].status);
						}
					}

					if (config.bluelive)
					{
						// Write result with live function
						live_entry(ri);
					}
					else if (config.bluepropro)
					{
						// Set output format for BlueProPro
						fprintf(outfile,"%s", dev_cache[ri].addr);
						fprintf(outfile,",0x%02x%02x%02x", dev_cache[ri].flags,\
						dev_cache[ri].major_class, dev_cache[ri].minor_class);
						fprintf(outfile,",%s\n", dev_cache[ri].name);
					}
					else
					{
						// Flush buffer
						memset(outbuffer, 0, sizeof(outbuffer));

						// Print time first if enabled
						if (config.showtime)
							sprintf(outbuffer,"[%s],", dev_cache[ri].time);

						// Always output MAC
						sprintf(outbuffer+strlen(outbuffer),"%s", dev_cache[ri].addr);

						// Optionally output class
						if (config.showclass)
							sprintf(outbuffer+strlen(outbuffer),",0x%02x%02x%02x", dev_cache[ri].flags,\
							dev_cache[ri].major_class, dev_cache[ri].minor_class);

						// "Friendly" version of class info
						if (config.friendlyclass)
							sprintf(outbuffer+strlen(outbuffer),",%s,(%s)",\
							device_class(dev_cache[ri].major_class, dev_cache[ri].minor_class),\
							device_capability(dev_cache[ri].flags));

						// Get manufacturer
						if (config.getmanufacturer)
							sprintf(outbuffer+strlen(outbuffer),",%s", mac_get_vendor(dev_cache[ri].priv_addr));

						// Append the name
						if (config.getname)
							sprintf(outbuffer+strlen(outbuffer),",%s", dev_cache[ri].name);

						// Append the status
						if (config.status)
							sprintf(outbuffer+strlen(outbuffer)," - %s", dev_cache[ri].status);

						// Send buffer, else file. File needs newline
						if (config.syslogonly)
							syslog(LOG_INFO,"%s", outbuffer);
						else if (config.udponly)
						{
							// Append newline to socket, kind of hacky
							sprintf(outbuffer+strlen(outbuffer),"\n");
							send_udp_msg(outbuffer);
						}
						else
							fprintf(outfile,"%s\n",outbuffer);
					}
					dev_cache[ri].print = 0;
					break;
				}
				// If we make it this far, it means we will check next stored device
			}

			// If there's a file open, write changes
			if (outfile != NULL)
				fflush(outfile);
		}

		// Now check if any devices are missing

		// Loop through the cache
		for (ri = 0; ri < cache_index; ri++)
		{

			for (i = 0; i <= num_results; i++)
			{
				// Return current MAC from struct
				ba2str(&(results+i)->bdaddr, addr);

				// Determine if device still present
				if (strcmp (addr, dev_cache[ri].priv_addr) == 0)
				{

					break;
				}

				// Device not found.
				if (i == num_results)
				{
					// The device is missing but not marked as gone -> it has just disappeared
					if (strcmp(dev_cache[ri].status, "gone") != 0)
					{
						// Devices aren't present every time. Wait a while before marking it gone
						if (dev_cache[ri].missing_count < 10)
						{
							dev_cache[ri].missing_count++;
						}
						else
						// It's really gone :(
						{
							strcpy(dev_cache[ri].status,"gone");

							// Print to console
							if (config.verbose) {
								printf("[%s] %s,%s - %s\n",\
										dev_cache[ri].time, dev_cache[ri].addr,\
										dev_cache[ri].name, dev_cache[ri].status);

							}

							// Flush buffer
							memset(exitbuffer, 0, sizeof(exitbuffer));

							// Print time first if enabled
							if (config.showtime)
								sprintf(exitbuffer,"[%s],", dev_cache[ri].time);

							// Always output MAC
							sprintf(exitbuffer+strlen(exitbuffer),"%s", dev_cache[ri].addr);

							// Append the name
							if (config.getname)
								sprintf(exitbuffer+strlen(exitbuffer),",%s", dev_cache[ri].name);

							// Append the status
							if (config.status)
								sprintf(exitbuffer+strlen(exitbuffer)," - %s", dev_cache[ri].status);

							// Send buffer, else file. File needs newline
							if (config.syslogonly)
								syslog(LOG_INFO,"%s", exitbuffer);
							else if (config.udponly)
							{
								// Append newline to socket, kind of hacky
								sprintf(exitbuffer+strlen(exitbuffer),"\n");
								send_udp_msg(exitbuffer);
							}
							else
								fprintf(outfile,"%s\n",exitbuffer);

							// If there's a file open, write changes
							if (outfile != NULL)
								fflush(outfile);

						}
					}

				}

			}

		}



	}
	// If we get here, shut down
	shut_down(0);
	// STFU
	return (1);
}
/*
 * XXX Ugly bit of code.  But, this is the only safe time that the
 * match between BIOS disks and native disks can be done.
 */
static void
matchbiosdisks(void)
{
	struct btinfo_biosgeom *big;
	struct bi_biosgeom_entry *be;
	device_t dv;
	deviter_t di;
	int i, ck, error, m, n;
	struct vnode *tv;
	char mbr[DEV_BSIZE];
	int dklist_size;
	int numbig;

	big = lookup_bootinfo(BTINFO_BIOSGEOM);

	numbig = big ? big->num : 0;

	/* First, count all native disks. */
	for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
	     dv = deviter_next(&di)) {
		if (is_valid_disk(dv))
			x86_ndisks++;
	}
	deviter_release(&di);

	dklist_size = sizeof(struct disklist) + (x86_ndisks - 1) *
	    sizeof(struct nativedisk_info);

	/* XXX M_TEMP is wrong */
	x86_alldisks = malloc(dklist_size, M_TEMP, M_NOWAIT | M_ZERO);
	if (x86_alldisks == NULL)
		return;

	x86_alldisks->dl_nnativedisks = x86_ndisks;
	x86_alldisks->dl_nbiosdisks = numbig;
	for (i = 0; i < numbig; i++) {
		x86_alldisks->dl_biosdisks[i].bi_dev = big->disk[i].dev;
		x86_alldisks->dl_biosdisks[i].bi_sec = big->disk[i].sec;
		x86_alldisks->dl_biosdisks[i].bi_head = big->disk[i].head;
		x86_alldisks->dl_biosdisks[i].bi_cyl = big->disk[i].cyl;
		x86_alldisks->dl_biosdisks[i].bi_lbasecs = big->disk[i].totsec;
		x86_alldisks->dl_biosdisks[i].bi_flags = big->disk[i].flags;
#ifdef GEOM_DEBUG
#ifdef notyet
		printf("disk %x: flags %x, interface %x, device %llx\n",
		       big->disk[i].dev, big->disk[i].flags,
		       big->disk[i].interface_path, big->disk[i].device_path);
#endif
#endif
	}

	/* XXX Code duplication from findroot(). */
	n = -1;
	for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
	     dv = deviter_next(&di)) {
		if (device_class(dv) != DV_DISK)
			continue;
#ifdef GEOM_DEBUG
		printf("matchbiosdisks: trying to match (%s) %s\n",
		    device_xname(dv), device_cfdata(dv)->cf_name);
#endif
		if (is_valid_disk(dv)) {
			n++;
			snprintf(x86_alldisks->dl_nativedisks[n].ni_devname,
			    sizeof(x86_alldisks->dl_nativedisks[n].ni_devname),
			    "%s", device_xname(dv));

			if ((tv = opendisk(dv)) == NULL)
				continue;

			error = vn_rdwr(UIO_READ, tv, mbr, DEV_BSIZE, 0,
			    UIO_SYSSPACE, 0, NOCRED, NULL, NULL);
			VOP_CLOSE(tv, FREAD, NOCRED);
			vput(tv);
			if (error) {
#ifdef GEOM_DEBUG
				printf("matchbiosdisks: %s: MBR read failure\n",
				    device_xname(dv));
#endif
				continue;
			}

			for (ck = i = 0; i < DEV_BSIZE; i++)
				ck += mbr[i];
			for (m = i = 0; i < numbig; i++) {
				be = &big->disk[i];
#ifdef GEOM_DEBUG
				printf("match %s with %d "
				    "dev ck %x bios ck %x\n", device_xname(dv), i,
				    ck, be->cksum);
#endif
				if (be->flags & BI_GEOM_INVALID)
					continue;
				if (be->cksum == ck &&
				    memcmp(&mbr[MBR_PART_OFFSET], be->mbrparts,
				        MBR_PART_COUNT *
					  sizeof(struct mbr_partition)) == 0) {
#ifdef GEOM_DEBUG
					printf("matched BIOS disk %x with %s\n",
					    be->dev, device_xname(dv));
#endif
					x86_alldisks->dl_nativedisks[n].
					    ni_biosmatches[m++] = i;
				}
			}
			x86_alldisks->dl_nativedisks[n].ni_nmatches = m;
		}
	}
	deviter_release(&di);
}
示例#23
0
/*
 * Mount a remote root fs via. NFS.  It goes like this:
 * - Call nfs_boot_init() to fill in the nfs_diskless struct
 * - build the rootfs mount point and call mountnfs() to do the rest.
 */
int
nfs_mountroot(void)
{
	struct timespec ts;
	struct nfs_diskless *nd;
	struct vattr attr;
	struct mount *mp;
	struct vnode *vp;
	struct lwp *l;
	long n;
	int error;

	l = curlwp; /* XXX */

	if (device_class(root_device) != DV_IFNET)
		return (ENODEV);

	/*
	 * XXX time must be non-zero when we init the interface or else
	 * the arp code will wedge.  [Fixed now in if_ether.c]
	 * However, the NFS attribute cache gives false "hits" when the
	 * current time < nfs_attrtimeo(nmp, np) so keep this in for now.
	 */
	if (time_second < NFS_MAXATTRTIMO) {
		ts.tv_sec = NFS_MAXATTRTIMO;
		ts.tv_nsec = 0;
		tc_setclock(&ts);
	}

	/*
	 * Call nfs_boot_init() to fill in the nfs_diskless struct.
	 * Side effect:  Finds and configures a network interface.
	 */
	nd = kmem_zalloc(sizeof(*nd), KM_SLEEP);
	error = nfs_boot_init(nd, l);
	if (error) {
		kmem_free(nd, sizeof(*nd));
		return (error);
	}

	/*
	 * Create the root mount point.
	 */
	error = nfs_mount_diskless(&nd->nd_root, "/", &mp, &vp, l);
	if (error)
		goto out;
	printf("root on %s\n", nd->nd_root.ndm_host);

	/*
	 * Link it into the mount list.
	 */
	mountlist_append(mp);
	rootvp = vp;
	mp->mnt_vnodecovered = NULLVP;
	vfs_unbusy(mp, false, NULL);

	/* Get root attributes (for the time). */
	vn_lock(vp, LK_SHARED | LK_RETRY);
	error = VOP_GETATTR(vp, &attr, l->l_cred);
	VOP_UNLOCK(vp);
	if (error)
		panic("nfs_mountroot: getattr for root");
	n = attr.va_atime.tv_sec;
#ifdef	DEBUG
	printf("root time: 0x%lx\n", n);
#endif
	setrootfstime(n);

out:
	if (error)
		nfs_boot_cleanup(nd, l);
	kmem_free(nd, sizeof(*nd));
	return (error);
}