/* brings interface up and runs a user-supplied script */
static int if_create()
{
	tap_fd = tap_open(tap_dev);
	if (tap_fd < 0) {
		wmlog_msg(0, "failed to allocate tap interface");
		wmlog_msg(0,
				"You should have TUN/TAP driver compiled in the kernel or as a kernel module.\n"
				"If 'modprobe tun' doesn't help then recompile your kernel.");
		exit_release_resources(1);
	}
	tap_set_hwaddr(tap_fd, tap_dev, wd_status.mac);
	tap_set_mtu(tap_fd, tap_dev, 1386);
	set_coe(tap_fd);
	wmlog_msg(0, "Allocated tap interface: %s", tap_dev);
	wmlog_msg(2, "Starting if-create script...");
	raise_event("if-create");
	return 0;
}
Exemple #2
0
static int set_data(unsigned char* data, int size)
{
	int r;
	int transferred;

	wmlog_dumphexasc(3, data, size, "Bulk write:");

	r = libusb_bulk_transfer(devh, EP_OUT, data, size, &transferred, 0);
	if (r < 0) {
		wmlog_msg(1, "bulk write error %d", r);
		if (r == LIBUSB_ERROR_NO_DEVICE) {
			exit_release_resources(0);
		}
		return r;
	}
	if (transferred < size) {
		wmlog_msg(1, "short write (%d)", r);
		return -1;
	}
	return r;
}
Exemple #3
0
/* brings interface up and runs a user-supplied script */
static int if_create()
{
	tap_fd = tap_open(tap_dev);
	if (tap_fd < 0) {
		wmlog_msg(0, "failed to allocate tap interface");
		wmlog_msg(0,
				"You should have TUN/TAP driver compiled in the kernel or as a kernel module.\n"
				"If 'modprobe tun' doesn't help then recompile your kernel.");
		exit_release_resources(1);
	}
	tap_set_hwaddr(tap_fd, tap_dev, wd_status.mac);
	tap_set_mtu(tap_fd, tap_dev, 1386);
	set_coe(tap_fd);
  
  //tap_dev pointed now to correct interface so we are free to update stistics paths
  sprintf(stat_rx_total_path, "/sys/class/net/%s/statistics/rx_bytes", tap_dev);
  sprintf(stat_tx_total_path, "/sys/class/net/%s/statistics/tx_bytes", tap_dev);
  
	wmlog_msg(0, "Allocated tap interface: %s", tap_dev);
	wmlog_msg(2, "Starting if-create script...");
	raise_event("if-create");
	return 0;
}
Exemple #4
0
int main(int argc, char **argv)
{
	struct sigaction sigact;
  struct sigevent sev;
  struct itimerspec its;
	int r = 1;

	parse_args(argc, argv);

	sigact.sa_handler = sighandler_exit;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigaction(SIGINT, &sigact, NULL);
	sigaction(SIGTERM, &sigact, NULL);
	sigaction(SIGQUIT, &sigact, NULL);
	sigact.sa_handler = sighandler_wait_child;
	sigaction(SIGCHLD, &sigact, NULL);
  sigact.sa_handler = sighandler_stats;
  sigfillset(&sigact.sa_mask);
  if (stats_period == 0)
    sigaction(SIGUSR1, &sigact, NULL);

	if (logfile != NULL) {
		set_wmlogger(argv[0], WMLOGGER_FILE, logfile);
	} else if (daemonize) {
		set_wmlogger(argv[0], WMLOGGER_SYSLOG, NULL);
	} else {
		set_wmlogger(argv[0], WMLOGGER_FILE, stderr);
	}

	if (daemonize) {
		daemon(0, 0);
	}
	
	if (stats_period != 0) {
    sigemptyset(&sigact.sa_mask);
    sigaction(SIGRTMIN, &sigact, NULL);
    
    // create the POSIX timer 
    sev.sigev_notify = SIGEV_SIGNAL;
    sev.sigev_signo = SIGRTMIN;
    sev.sigev_value.sival_ptr = (void *) &timerid;
    if (timer_create(CLOCK_MONOTONIC, &sev, &timerid) == 0) {
        // start the POSIX timer
        its.it_value.tv_sec = stats_period;
        its.it_value.tv_nsec = 0;
        its.it_interval.tv_sec = its.it_value.tv_sec;
        its.it_interval.tv_nsec = its.it_value.tv_nsec;
        timer_settime(timerid, 0, &its, NULL);
    }
  }

	r = libusb_init(&ctx);
	if (r < 0) {
		wmlog_msg(0, "failed to initialise libusb");
		exit_release_resources(1);
	}
	
	if (pid_fname && !write_pidfile(pid_fname)) {
    wmlog_msg(0, "failed to create pid file %s", pid_fname);
    exit_release_resources(1);
  }

	devh = find_wimax_device();
	if (devh == NULL) {
		wmlog_msg(0, "Could not find/open device");
		exit_release_resources(1);
	}

	wmlog_msg(0, "Device found");

	if (detach_dvd && libusb_kernel_driver_active(devh, IF_DVD) == 1) {
		r = libusb_detach_kernel_driver(devh, IF_DVD);
		if (r < 0) {
			wmlog_msg(0, "kernel driver detach error %d", r);
		} else {
			wmlog_msg(0, "detached pseudo-DVD kernel driver");
		}
	}

	if (libusb_kernel_driver_active(devh, IF_MODEM) == 1) {
		kernel_driver_active = 1;
		r = libusb_detach_kernel_driver(devh, IF_MODEM);
		if (r < 0) {
			wmlog_msg(0, "kernel driver detach error %d", r);
		} else {
			wmlog_msg(0, "detached modem kernel driver");
		}
	}

	r = libusb_claim_interface(devh, IF_MODEM);
	if (r < 0) {
		wmlog_msg(0, "Claim usb interface error %d", r);
		exit_release_resources(1);
	}
	wmlog_msg(0, "Claimed interface");

	alloc_fds();
	libusb_set_pollfd_notifiers(ctx, cb_add_pollfd, cb_remove_pollfd, NULL);

	r = init();
	if (r < 0) {
		wmlog_msg(0, "init error %d", r);
		exit_release_resources(1);
	}

	if_create();
	cb_add_pollfd(tap_fd, POLLIN, NULL);

	r = scan_loop();
	if (r < 0) {
		wmlog_msg(0, "scan_loop error %d", r);
		exit_release_resources(1);
	}

	exit_release_resources(0);
	return 0;
}
Exemple #5
0
static void sighandler_exit(int signum) {
	exit_release_resources(0);
}
Exemple #6
0
static int process_events_once(int timeout)
{
	struct timeval tv = {0, 0};
	int r;
	int libusb_delay;
	int delay;
	unsigned int i;
	char process_libusb = 0;

	r = libusb_get_next_timeout(ctx, &tv);
	if (r == 1 && tv.tv_sec == 0 && tv.tv_usec == 0)
	{
		r = libusb_handle_events_timeout(ctx, &tv);
	}

	delay = libusb_delay = tv.tv_sec * 1000 + tv.tv_usec;
	if (delay <= 0 || delay > timeout)
	{
		delay = timeout;
	}

	CHECK_NEGATIVE(poll(fds, nfds, delay));

	process_libusb = (r == 0 && delay == libusb_delay);

	for (i = 0; i < nfds; ++i)
	{
		if (fds[i].fd == tap_fd) {
			if (fds[i].revents)
			{
				CHECK_NEGATIVE(read_tap());
			}
			continue;
		}
		process_libusb |= fds[i].revents;
	}

	if (process_libusb)
	{
		struct timeval tv = {.tv_sec = 0, .tv_usec = 0};
		CHECK_NEGATIVE(libusb_handle_events_timeout(ctx, &tv));
	}

	return 0;
}

/* handle events until timeout is reached or all of the events in event_mask happen */
static int process_events_by_mask(int timeout, unsigned int event_mask)
{
	struct timeval start, curr;
	int r;
	int delay = timeout;

	CHECK_NEGATIVE(gettimeofday(&start, NULL));

	wd_status.info_updated &= ~event_mask;

	while ((event_mask == 0 || (wd_status.info_updated & event_mask) != event_mask) && delay >= 0) {
		long a;

		CHECK_NEGATIVE(process_events_once(delay));

		if (device_disconnected) {
			exit_release_resources(0);
		}

		CHECK_NEGATIVE(gettimeofday(&curr, NULL));

		a = (curr.tv_sec - start.tv_sec) * 1000 + (curr.tv_usec - start.tv_usec) / 1000;
		delay = timeout - a;
	}

	wd_status.info_updated &= ~event_mask;

	return (delay > 0) ? delay : 0;
}

int alloc_fds()
{
	int i;
	const struct libusb_pollfd **usb_fds = libusb_get_pollfds(ctx);

	if (!usb_fds)
	{
		return -1;
	}

	nfds = 0;
	while (usb_fds[nfds])
	{
		nfds++;
	}
	if (tap_fd != -1) {
		nfds++;
	}

	if(fds != NULL) {
		free(fds);
	}

	fds = (struct pollfd*)calloc(nfds, sizeof(struct pollfd));
	for (i = 0; usb_fds[i]; ++i)
	{
		fds[i].fd = usb_fds[i]->fd;
		fds[i].events = usb_fds[i]->events;
		set_coe(usb_fds[i]->fd);
	}
	if (tap_fd != -1) {
		fds[i].fd = tap_fd;
		fds[i].events = POLLIN;
		fds[i].revents = 0;
	}

	free(usb_fds);

	return 0;
}
int main(int argc, char **argv)
{
	struct sigaction sigact;
	int r = 1;

	parse_args(argc, argv);

	sigact.sa_handler = sighandler_exit;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigaction(SIGINT, &sigact, NULL);
	sigaction(SIGTERM, &sigact, NULL);
	sigaction(SIGQUIT, &sigact, NULL);
	sigact.sa_handler = sighandler_wait_child;
	sigaction(SIGCHLD, &sigact, NULL);

	if (logfile != NULL) {
		set_wmlogger(argv[0], WMLOGGER_FILE, logfile);
	} else if (daemonize) {
		set_wmlogger(argv[0], WMLOGGER_SYSLOG, NULL);
	} else {
		set_wmlogger(argv[0], WMLOGGER_FILE, stderr);
	}

	if (daemonize) {
		daemon(0, 0);
	}

	r = libusb_init(&ctx);
	if (r < 0) {
		wmlog_msg(0, "failed to initialise libusb");
		exit_release_resources(1);
	}

	devh = find_wimax_device();
	if (devh == NULL) {
		wmlog_msg(0, "Could not find/open device");
		exit_release_resources(1);
	}

	wmlog_msg(0, "Device found");

	if (detach_dvd && libusb_kernel_driver_active(devh, IF_DVD) == 1) {
		r = libusb_detach_kernel_driver(devh, IF_DVD);
		if (r < 0) {
			wmlog_msg(0, "kernel driver detach error %d", r);
		} else {
			wmlog_msg(0, "detached pseudo-DVD kernel driver");
		}
	}

	if (libusb_kernel_driver_active(devh, IF_MODEM) == 1) {
		kernel_driver_active = 1;
		r = libusb_detach_kernel_driver(devh, IF_MODEM);
		if (r < 0) {
			wmlog_msg(0, "kernel driver detach error %d", r);
		} else {
			wmlog_msg(0, "detached modem kernel driver");
		}
	}

	r = libusb_claim_interface(devh, IF_MODEM);
	if (r < 0) {
		wmlog_msg(0, "Claim usb interface error %d", r);
		exit_release_resources(1);
	}
	wmlog_msg(0, "Claimed interface");

	alloc_fds();
	libusb_set_pollfd_notifiers(ctx, cb_add_pollfd, cb_remove_pollfd, NULL);

	r = init();
	if (r < 0) {
		wmlog_msg(0, "init error %d", r);
		exit_release_resources(1);
	}

	if_create();
	cb_add_pollfd(tap_fd, POLLIN, NULL);

	r = scan_loop();
	if (r < 0) {
		wmlog_msg(0, "scan_loop error %d", r);
		exit_release_resources(1);
	}

	exit_release_resources(0);
	return 0;
}