Exemple #1
0
static int
usb_activate(pcap_t* handle)
{
	struct pcap_usb_linux *handlep = handle->private;
	char 		full_path[USB_LINE_LEN];

	/* Initialize some components of the pcap structure. */
	handle->bufsize = handle->snapshot;
	handle->offset = 0;
	handle->linktype = DLT_USB_LINUX;

	handle->inject_op = usb_inject_linux;
	handle->setfilter_op = install_bpf_program; /* no kernel filtering */
	handle->setdirection_op = usb_setdirection_linux;
	handle->set_datalink_op = NULL;	/* can't change data link type */
	handle->getnonblock_op = pcap_getnonblock_fd;
	handle->setnonblock_op = pcap_setnonblock_fd;

	/*get usb bus index from device name */
	if (sscanf(handle->opt.source, USB_IFACE"%d", &handlep->bus_index) != 1)
	{
		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
			"Can't get USB bus index from %s", handle->opt.source);
		return PCAP_ERROR;
	}

	/*now select the read method: try to open binary interface */
	snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index);  
	handle->fd = open(full_path, O_RDONLY, 0);
	if (handle->fd >= 0)
	{
		if (handle->opt.rfmon) {
			/*
			 * Monitor mode doesn't apply to USB devices.
			 */
			close(handle->fd);
			return PCAP_ERROR_RFMON_NOTSUP;
		}

		/* binary api is available, try to use fast mmap access */
		if (usb_mmap(handle)) {
			handle->linktype = DLT_USB_LINUX_MMAPPED;
			handle->stats_op = usb_stats_linux_bin;
			handle->read_op = usb_read_linux_mmap;
			handle->cleanup_op = usb_cleanup_linux_mmap;
			probe_devices(handlep->bus_index);

			/*
			 * "handle->fd" is a real file, so "select()" and
			 * "poll()" work on it.
			 */
			handle->selectable_fd = handle->fd;
			return 0;
		}

		/* can't mmap, use plain binary interface access */
		handle->stats_op = usb_stats_linux_bin;
		handle->read_op = usb_read_linux_bin;
		probe_devices(handlep->bus_index);
	}
	else {
		/*Binary interface not available, try open text interface */
		snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR"/%dt", handlep->bus_index);  
		handle->fd = open(full_path, O_RDONLY, 0);
		if (handle->fd < 0)
		{
			if (errno == ENOENT)
			{
				/*
				 * Not found at the new location; try
				 * the old location.
				 */
				snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%dt", handlep->bus_index);  
				handle->fd = open(full_path, O_RDONLY, 0);
			}
			if (handle->fd < 0) {
				/* no more fallback, give it up*/
				snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
					"Can't open USB bus file %s: %s", full_path, strerror(errno));
				return PCAP_ERROR;
			}
		}

		if (handle->opt.rfmon) {
			/*
			 * Monitor mode doesn't apply to USB devices.
			 */
			close(handle->fd);
			return PCAP_ERROR_RFMON_NOTSUP;
		}

		handle->stats_op = usb_stats_linux;
		handle->read_op = usb_read_linux;
	}

	/*
	 * "handle->fd" is a real file, so "select()" and "poll()"
	 * work on it.
	 */
	handle->selectable_fd = handle->fd;

	/* for plain binary access and text access we need to allocate the read
	 * buffer */
	handle->buffer = malloc(handle->bufsize);
	if (!handle->buffer) {
		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
			 "malloc: %s", pcap_strerror(errno));
		close(handle->fd);
		return PCAP_ERROR;
	}
	return 0;
}
Exemple #2
0
static int
usb_activate(pcap_t* handle)
{
	struct pcap_usb_linux *handlep = handle->priv;
	char 		full_path[USB_LINE_LEN];

	/*
	 * Turn a negative snapshot value (invalid), a snapshot value of
	 * 0 (unspecified), or a value bigger than the normal maximum
	 * value, into the maximum allowed value.
	 *
	 * If some application really *needs* a bigger snapshot
	 * length, we should just increase MAXIMUM_SNAPLEN.
	 */
	if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN)
		handle->snapshot = MAXIMUM_SNAPLEN;

	/* Initialize some components of the pcap structure. */
	handle->bufsize = handle->snapshot;
	handle->offset = 0;
	handle->linktype = DLT_USB_LINUX;

	handle->inject_op = usb_inject_linux;
	handle->setfilter_op = install_bpf_program; /* no kernel filtering */
	handle->setdirection_op = usb_setdirection_linux;
	handle->set_datalink_op = NULL;	/* can't change data link type */
	handle->getnonblock_op = pcap_getnonblock_fd;
	handle->setnonblock_op = pcap_setnonblock_fd;

	/*get usb bus index from device name */
	if (sscanf(handle->opt.device, USB_IFACE"%d", &handlep->bus_index) != 1)
	{
		pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
			"Can't get USB bus index from %s", handle->opt.device);
		return PCAP_ERROR;
	}

	if (have_binary_usbmon())
	{
		/*
		 * We have binary-mode support.
		 * Try to open the binary interface.
		 */
		pcap_snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index);
		handle->fd = open(full_path, O_RDONLY, 0);
		if (handle->fd < 0)
		{
			/*
			 * The attempt failed; why?
			 */
			switch (errno) {

			case ENOENT:
				/*
				 * The device doesn't exist.
				 * That could either mean that there's
				 * no support for monitoring USB buses
				 * (which probably means "the usbmon
				 * module isn't loaded") or that there
				 * is but that *particular* device
				 * doesn't exist (no "scan all buses"
				 * device if the bus index is 0, no
				 * such bus if the bus index isn't 0).
				 */
				return PCAP_ERROR_NO_SUCH_DEVICE;

			case EACCES:
				/*
				 * We didn't have permission to open it.
				 */
				return PCAP_ERROR_PERM_DENIED;

			default:
				/*
				 * Something went wrong.
				 */
				pcap_fmt_errmsg_for_errno(handle->errbuf,
				    PCAP_ERRBUF_SIZE, errno,
				    "Can't open USB bus file %s", full_path);
				return PCAP_ERROR;
			}
		}

		if (handle->opt.rfmon)
		{
			/*
			 * Monitor mode doesn't apply to USB devices.
			 */
			close(handle->fd);
			return PCAP_ERROR_RFMON_NOTSUP;
		}

		/* try to use fast mmap access */
		if (usb_mmap(handle))
		{
			handle->linktype = DLT_USB_LINUX_MMAPPED;
			handle->stats_op = usb_stats_linux_bin;
			handle->read_op = usb_read_linux_mmap;
			handle->cleanup_op = usb_cleanup_linux_mmap;
#ifdef HAVE_LINUX_USBDEVICE_FS_H
			probe_devices(handlep->bus_index);
#endif

			/*
			 * "handle->fd" is a real file, so
			 * "select()" and "poll()" work on it.
			 */
			handle->selectable_fd = handle->fd;
			return 0;
		}

		/* can't mmap, use plain binary interface access */
		handle->stats_op = usb_stats_linux_bin;
		handle->read_op = usb_read_linux_bin;
#ifdef HAVE_LINUX_USBDEVICE_FS_H
		probe_devices(handlep->bus_index);
#endif
	}
	else {
		/*
		 * We don't have binary mode support.
		 * Try opening the text-mode device.
		 */
		pcap_snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR"/%dt", handlep->bus_index);
		handle->fd = open(full_path, O_RDONLY, 0);
		if (handle->fd < 0)
		{
			if (errno == ENOENT)
			{
				/*
				 * Not found at the new location; try
				 * the old location.
				 */
				pcap_snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%dt", handlep->bus_index);
				handle->fd = open(full_path, O_RDONLY, 0);
			}
			if (handle->fd < 0) {
				/*
				 * Is the problem that we didn't have
				 * sufficient permission to open it?
				 */
				if (errno == EACCES) {
					/*
					 * Yes - return that error.
					 */
					return PCAP_ERROR_PERM_DENIED;
				}

				/*
				 * No - was the problem something other
				 * than "it doesn't exist"?
				 */
				if (errno != ENOENT) {
					/*
					 * Yes - return *that* error.
					 */
					pcap_fmt_errmsg_for_errno(handle->errbuf,
					    PCAP_ERRBUF_SIZE, errno,
					    "Can't open USB bus file %s",
					    full_path);
					return PCAP_ERROR;
				}

				/*
				 * No.  Report that as "no such device".
				 * (That could mean "no such USB bus"
				 * or "monitoring not supported".)
				 */
				return PCAP_ERROR_NO_SUCH_DEVICE;
			}
		}

		if (handle->opt.rfmon)
		{
			/*
			 * Monitor mode doesn't apply to USB devices.
			 */
			close(handle->fd);
			return PCAP_ERROR_RFMON_NOTSUP;
		}

		handle->stats_op = usb_stats_linux;
		handle->read_op = usb_read_linux;
	}

	/*
	 * "handle->fd" is a real file, so "select()" and "poll()"
	 * work on it.
	 */
	handle->selectable_fd = handle->fd;

	/* for plain binary access and text access we need to allocate the read
	 * buffer */
	handle->buffer = malloc(handle->bufsize);
	if (!handle->buffer) {
		pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
		    errno, "malloc");
		close(handle->fd);
		return PCAP_ERROR;
	}
	return 0;
}