/* 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; }
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; }
/* 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; }
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; }
static void sighandler_exit(int signum) { exit_release_resources(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; }