static int olsr(int fd,char *s) { char *nextargs = NULL, *arg; struct olsr_setup *olsr_settings; struct vder_iface *selected = NULL; enum command_action_enum action = -1; static pthread_t olsr_thread; arg = strtok_r(s, " ", &nextargs); if(!arg) { printoutc(fd, "Error: arguments required"); return EINVAL; } if ((!arg) || (strlen(arg) < 4) || ((strncmp(arg, "start", 5) != 0) && (strncmp(arg, "stop", 4) != 0))) { printoutc(fd, "Invalid action \"%s\".", arg); return EINVAL; } if (strncmp(arg, "start", 5) == 0) action = ACTION_ADD; else action = ACTION_DELETE; if (action == ACTION_ADD) { olsr_settings = malloc(sizeof(struct olsr_setup)); memset(olsr_settings, 0, sizeof(struct olsr_setup)); arg = strtok_r(NULL, " ", &nextargs); while (arg) { if ((strlen(arg) < 4) || (strncmp(arg, "eth", 3)!= 0)) { printoutc(fd, "Invalid interface \"%s\".", arg); free(olsr_settings); return EINVAL; } selected = select_interface(arg); if (!selected) { free(olsr_settings); return ENXIO; } olsr_settings->ifaces[olsr_settings->n_ifaces++] = selected; arg = strtok_r(NULL, " ", &nextargs); } if (olsr_settings->n_ifaces == 0) { free(olsr_settings); return EINVAL; } pthread_create(&olsr_thread, 0, vder_olsr_loop, olsr_settings); } else { pthread_cancel(olsr_thread); /* stop */ } return 0; }
static int jlink_init(void) { int ret; struct jaylink_device **devs; unsigned int i; bool found_device; uint32_t tmp; char *firmware_version; struct jaylink_hardware_version hwver; struct jaylink_hardware_status hwstatus; ret = jaylink_init(&jayctx); if (ret != JAYLINK_OK) { LOG_ERROR("jaylink_init() failed: %s.", jaylink_strerror_name(ret)); return ERROR_JTAG_INIT_FAILED; } ret = jaylink_get_device_list(jayctx, &devs); if (ret < 0) { LOG_ERROR("jaylink_get_device_list() failed: %s.", jaylink_strerror_name(ret)); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; } found_device = false; if (!use_serial_number && !use_usb_address) LOG_INFO("No device selected, using first device."); for (i = 0; devs[i]; i++) { jaylink_device_get_serial_number(devs[i], &tmp); ret = jaylink_device_get_usb_address(devs[i]); if (use_usb_address && usb_address != ret) continue; if (use_serial_number && tmp != serial_number) continue; ret = jaylink_open(devs[i], &devh); if (ret != JAYLINK_OK) { LOG_ERROR("Failed to open device: %s.", jaylink_strerror_name(ret)); continue; } found_device = true; break; } jaylink_free_device_list(devs, 1); if (!found_device) { LOG_ERROR("No J-Link device found."); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; } /* * Be careful with changing the following initialization sequence because * some devices are known to be sensitive regarding the order. */ ret = jaylink_get_firmware_version(devh, &firmware_version); if (ret > 0) { LOG_INFO("%s", firmware_version); free(firmware_version); } else if (!ret) { LOG_WARNING("Device responds empty firmware version string."); } else { LOG_ERROR("jaylink_get_firmware_version() failed: %s.", jaylink_strerror_name(ret)); jaylink_close(devh); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; } memset(caps, 0, JAYLINK_DEV_EXT_CAPS_SIZE); ret = jaylink_get_caps(devh, caps); if (ret != JAYLINK_OK) { LOG_ERROR("jaylink_get_caps() failed: %s.", jaylink_strerror_name(ret)); jaylink_close(devh); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; } if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_EXT_CAPS)) { ret = jaylink_get_extended_caps(devh, caps); if (ret != JAYLINK_OK) { LOG_ERROR("jaylink_get_extended_caps() failed: %s.", jaylink_strerror_name(ret)); jaylink_close(devh); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; } } jtag_command_version = JAYLINK_JTAG_V2; if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_HW_VERSION)) { ret = jaylink_get_hardware_version(devh, &hwver); if (ret != JAYLINK_OK) { LOG_ERROR("Failed to retrieve hardware version: %s.", jaylink_strerror_name(ret)); jaylink_close(devh); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; } LOG_INFO("Hardware version: %u.%02u", hwver.major, hwver.minor); if (hwver.major >= 5) jtag_command_version = JAYLINK_JTAG_V3; } if (iface == JAYLINK_TIF_SWD) { /* * Adjust the SWD transaction buffer size in case there is already * allocated memory on the device. This happens for example if the * memory for SWO capturing is still allocated because the software * which used the device before has not been shut down properly. */ if (!adjust_swd_buffer_size()) { jaylink_close(devh); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; } } if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { if (!read_device_config(&config)) { LOG_ERROR("Failed to read device configuration data."); jaylink_close(devh); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; } memcpy(&tmp_config, &config, sizeof(struct device_config)); } ret = jaylink_get_hardware_status(devh, &hwstatus); if (ret != JAYLINK_OK) { LOG_ERROR("jaylink_get_hardware_status() failed: %s.", jaylink_strerror_name(ret)); jaylink_close(devh); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; } LOG_INFO("VTarget = %u.%03u V", hwstatus.target_voltage / 1000, hwstatus.target_voltage % 1000); conn.handle = 0; conn.pid = 0; conn.hid = 0; conn.iid = 0; conn.cid = 0; ret = jlink_register(); if (ret != ERROR_OK) { jaylink_close(devh); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; } ret = select_interface(); if (ret != ERROR_OK) { jaylink_close(devh); jaylink_exit(jayctx); return ret; } jlink_reset(0, 0); jtag_sleep(3000); jlink_tap_init(); jlink_speed(jtag_get_speed_khz()); if (iface == JAYLINK_TIF_JTAG) { /* * J-Link devices with firmware version v5 and v6 seems to have an issue * if the first tap move is not divisible by 8, so we send a TLR on * first power up. */ uint8_t tms = 0xff; jlink_clock_data(NULL, 0, &tms, 0, NULL, 0, 8); jlink_flush(); } return ERROR_OK; }
/* * main() - loop forever, reading the hdaps values and * parking/unparking as necessary */ int main (int argc, char** argv) { struct utsname sysinfo; struct list *p = NULL; int c, park_now, protect_factor; int x = 0, y = 0, z = 0; int fd, i, ret, threshold = 15, adaptive = 0, pidfile = 0, parked = 0, forceadd = 0; double unow = 0, parked_utime = 0; struct option longopts[] = { {"device", required_argument, NULL, 'd'}, {"sensitivity", required_argument, NULL, 's'}, {"adaptive", no_argument, NULL, 'a'}, {"verbose", no_argument, NULL, 'v'}, {"background", no_argument, NULL, 'b'}, {"pidfile", optional_argument, NULL, 'p'}, {"dry-run", no_argument, NULL, 't'}, {"poll-sysfs", no_argument, NULL, 'y'}, {"version", no_argument, NULL, 'V'}, {"help", no_argument, NULL, 'h'}, {"syslog", no_argument, NULL, 'l'}, {"force", no_argument, NULL, 'f'}, {NULL, 0, NULL, 0} }; if (uname(&sysinfo) < 0 || strcmp("2.6.27", sysinfo.release) <= 0) { protect_factor = 1000; kernel_interface = UNLOAD_HEADS; } else { protect_factor = 1; kernel_interface = PROTECT; } openlog(PACKAGE_NAME, LOG_PID, LOG_DAEMON); while ((c = getopt_long(argc, argv, "d:s:vbap::tyVhlf", longopts, NULL)) != -1) { switch (c) { case 'd': add_disk(optarg); break; case 's': threshold = atoi(optarg); break; case 'b': background = 1; break; case 'a': adaptive = 1; break; case 'v': verbose = 1; break; case 'p': pidfile = 1; if (optarg == NULL) { snprintf(pid_file, sizeof(pid_file), "%s", PID_FILE); } else { snprintf(pid_file, sizeof(pid_file), "%s", optarg); } break; case 't': printlog(stdout, "Dry run, will not actually park heads or freeze queue."); dry_run = 1; break; case 'y': poll_sysfs = 1; break; case 'V': version(); break; case 'l': dosyslog = 1; break; case 'f': forceadd = 1; break; case 'h': default: usage(); break; } } printlog(stdout, "Starting "PACKAGE_NAME); if (disklist && forceadd) { char protect_method[FILENAME_MAX] = ""; p = disklist; while (p != NULL) { snprintf(protect_method, sizeof(protect_method), QUEUE_METHOD_FMT, p->name); if (kernel_interface == UNLOAD_HEADS) fd = open (p->protect_file, O_RDWR); else fd = open (protect_method, O_RDWR); if (fd > 0) { if (kernel_interface == UNLOAD_HEADS) ret = write(fd, FORCE_UNLOAD_HEADS, strlen(FORCE_UNLOAD_HEADS)); else ret = write(fd, FORCE_PROTECT_METHOD, strlen(FORCE_PROTECT_METHOD)); if (ret == -1) printlog(stderr, "Could not forcely enable UNLOAD feature for %s", p->name); else printlog(stdout, "Forcely enabled UNLOAD for %s", p->name); close(fd); } else printlog(stderr, "Could not open %s for forcely enabling UNLOAD feature", p->protect_file); p = p->next; } } if (disklist == NULL) { printlog(stdout, "WARNING: You did not supply any devices to protect, trying autodetection."); if (autodetect_devices() < 1) printlog(stderr, "Could not detect any devices."); } if (disklist == NULL) usage(argv); /* Let's see if we're on a ThinkPad or on an *Book */ select_interface(0); if (!position_interface) select_interface(1); if (!position_interface) { printlog(stdout, "Could not find a suitable interface"); return -1; } else printlog(stdout, "Selected interface: %s", interface_names[position_interface]); if (!poll_sysfs) { if (position_interface == INTERFACE_HDAPS) { hdaps_input_nr = device_find_byphys("hdaps/input1"); hdaps_input_fd = device_open(hdaps_input_nr); if (hdaps_input_fd < 0) { printlog(stdout, "WARNING: Could not find hdaps input device (%s). " "You may be using an incompatible version of the hdaps module. " "Falling back to reading the position from sysfs (uses more power).\n" "Use '-y' to silence this warning.", strerror(errno)); poll_sysfs = 1; } else { printlog(stdout, "Selected HDAPS input device: /dev/input/event%d", hdaps_input_nr); } } else if (position_interface == INTERFACE_AMS) { hdaps_input_nr = device_find_byname("Apple Motion Sensor"); hdaps_input_fd = device_open(hdaps_input_nr); if (hdaps_input_fd < 0) { printlog(stdout, "WARNING: Could not find AMS input device, do you need to set joystick=1?"); poll_sysfs = 1; } else { printlog(stdout, "Selected AMS input device /dev/input/event%d", hdaps_input_nr); } } } if (background) { verbose = 0; if (pidfile) { fd = open (pid_file, O_WRONLY | O_CREAT, 0644); if (fd < 0) { printlog (stderr, "Could not create pidfile: %s", pid_file); return 1; } } daemon(0,0); if (pidfile) { char buf[BUF_LEN]; snprintf (buf, sizeof(buf), "%d\n", getpid()); ret = write (fd, buf, strlen(buf)); if (ret < 0) { printlog (stderr, "Could not write to pidfile %s", pid_file); return 1; } if (close (fd)) { printlog (stderr, "Could not close pidfile %s", pid_file); return 1; } } } mlockall(MCL_FUTURE); if (verbose) { p = disklist; while (p != NULL) { printf("disk: %s\n", p->name); p = p->next; } printf("threshold: %i\n", threshold); printf("read_method: %s\n", poll_sysfs ? "poll-sysfs" : "input-dev"); } /* check the protect attribute exists */ /* wait for it if it's not there (in case the attribute hasn't been created yet) */ p = disklist; while (p != NULL && !dry_run) { fd = open (p->protect_file, O_RDWR); if (background) for (i = 0; fd < 0 && i < 100; ++i) { usleep (100000); /* 10 Hz */ fd = open (p->protect_file, O_RDWR); } if (fd < 0) { printlog (stderr, "Could not open %s\nDoes your kernel/drive support IDLE_IMMEDIATE with UNLOAD?", p->protect_file); free_disk(disklist); return 1; } close (fd); p = p->next; } /* see if we can read the sensor */ /* wait for it if it's not there (in case the attribute hasn't been created yet) */ ret = read_position_from_sysfs (&x, &y, &z); if (background) for (i = 0; ret && i < 100; ++i) { usleep (100000); /* 10 Hz */ ret = read_position_from_sysfs (&x, &y, &z); } if (ret) { printlog(stderr, "Could not read position from sysfs."); return 1; } /* adapt to the driver's sampling rate */ if (position_interface == INTERFACE_HDAPS) sampling_rate = read_int(SAMPLING_RATE_FILE); if (sampling_rate <= 0) sampling_rate = DEFAULT_SAMPLING_RATE; if (verbose) printf("sampling_rate: %d\n", sampling_rate); signal(SIGUSR1, SIGUSR1_handler); signal(SIGTERM, SIGTERM_handler); while (running) { if (poll_sysfs) { usleep (1000000/sampling_rate); ret = read_position_from_sysfs (&x, &y, &z); unow = get_utime(); /* microsec */ } else { double oldunow = unow; int oldx = x, oldy = y, oldz = z; ret = read_position_from_inputdev (&x, &y, &z, &unow); /* The input device issues events only when the position changed. * The analysis state needs to know how long the position remained * unchanged, so send analyze() a fake retroactive update before sending * the new one. */ if (!ret && oldunow && unow-oldunow > 1.5/sampling_rate) analyze(oldx, oldy, unow-1.0/sampling_rate, threshold, adaptive, parked); } if (ret) { if (verbose) printf("readout error (%d)\n", ret); continue; } park_now = analyze(x, y, unow, threshold, adaptive, parked); if (park_now && !pause_now) { if (!parked || unow>parked_utime+REFREEZE_SECONDS) { /* Not frozen or freeze about to expire */ p = disklist; while (p != NULL) { write_protect(p->protect_file, (FREEZE_SECONDS+FREEZE_EXTRA_SECONDS) * protect_factor); p = p->next; } /* Write protect before any output (xterm, or * whatever else is handling our stdout, may be * swapped out). */ if (!parked) printlog(stdout, "parking"); parked = 1; parked_utime = unow; } } else { if (parked && (pause_now || unow>parked_utime+FREEZE_SECONDS)) { /* Sanity check */ p = disklist; while (p != NULL) { if (!dry_run && !read_int(p->protect_file)) printlog(stderr, "Error! Not parked when we " "thought we were... (paged out " "and timer expired?)"); /* Freeze has expired */ write_protect(p->protect_file, 0); /* unprotect */ p = p->next; } parked = 0; printlog(stdout, "un-parking"); } while (pause_now) { pause_now = 0; printlog(stdout, "pausing for %d seconds", SIGUSR1_SLEEP_SEC); sleep(SIGUSR1_SLEEP_SEC); } } } free_disk(disklist); printlog(stdout, "Terminating "PACKAGE_NAME); closelog(); if (pidfile) unlink(pid_file); munlockall(); return ret; }
static int filter(int fd,char *s) { struct vder_filter *cur = Router.filtering_table; int action; struct vder_iface *vif = NULL; uint8_t proto = 0; struct in_addr s_addr = {0}, s_nm = {0}, d_addr = {0}, d_nm = {0}; uint16_t sport = 0, dport = 0; int tos = -1; uint8_t priority = PRIO_BESTEFFORT; enum filter_action filter_action = filter_invalid; char *nextargs = NULL, *arg; arg = strtok_r(s, " ", &nextargs); if(!arg) { /* No arguments */ while(cur) { show_filter(fd, cur); cur = cur->next; } return 0; } if ((!arg) || (strlen(arg) != 3) || ((strncmp(arg, "add", 3) != 0) && (strncmp(arg, "del", 3) != 0))) { printoutc(fd, "Invalid action \"%s\".", arg); return EINVAL; } if (strncmp(arg, "del", 3) == 0) action = ACTION_DELETE; else action = ACTION_ADD; arg = strtok_r(NULL, " ", &nextargs); if (!arg) { not_understood(fd, ""); return EINVAL; } while(arg) { if (match_input("src", arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; vif = select_interface(arg); } else if(match_input("proto", arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; if (not_a_number(arg)) { if (match_input("tcp", arg)) proto = IPPROTO_TCP; else if (match_input("udp", arg)) proto = IPPROTO_UDP; else if (match_input("igmp", arg)) proto = IPPROTO_IGMP; else if (match_input("icmp", arg)) proto = IPPROTO_ICMP; else { printoutc(fd, "Invalid protocol \"%s\"", arg); return EINVAL; } } else { proto = atoi(arg); if (proto <= 0) { printoutc(fd, "Invalid protocol \"%s\"", arg); return EINVAL; } } } else if (match_input("from",arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; if (!inet_aton(arg, &s_addr) || !is_unicast(s_addr.s_addr)) { printoutc(fd, "Invalid from address \"%s\"", arg); return EINVAL; } arg = strtok_r(NULL, " ", &nextargs); if (!arg) { printoutc(fd, "from address: netmask is required"); return EINVAL; } if (!inet_aton(arg, &s_nm) || !is_netmask(s_nm.s_addr)) { printoutc(fd, "Invalid netmask \"%s\"", arg); return EINVAL; } } else if (match_input("to",arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; if (!inet_aton(arg, &d_addr) || !is_unicast(d_addr.s_addr)) { printoutc(fd, "Invalid from address \"%s\"", arg); return EINVAL; } arg = strtok_r(NULL, " ", &nextargs); if (!arg) { printoutc(fd, "from address: netmask is required"); return EINVAL; } if (!inet_aton(arg, &d_nm) || !is_netmask(d_nm.s_addr)) { printoutc(fd, "Invalid netmask \"%s\"", arg); return EINVAL; } } else if (match_input("tos",arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; tos = atoi(arg); if ((tos < 0) || not_a_number(arg)) { printoutc(fd, "Invalid tos %s", arg); return EINVAL; } } else if (match_input("sport",arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; if ((sport < 0) || not_a_number(arg)) { printoutc(fd, "Invalid sport %s", arg); return EINVAL; } sport = htons(atoi(arg)); } else if (match_input("dport",arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; if (not_a_number(arg)) { printoutc(fd, "Invalid dport %s", arg); return EINVAL; } dport = htons(atoi(arg)); } else if (match_input("prio",arg)) { if (filter_action != filter_invalid) { printoutc(fd, "Invalid double action for filter"); } arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; priority = atoi(arg); if ((priority < 0) || (priority >= PRIO_NUM) || not_a_number(arg)) { printoutc(fd, "Invalid priority %s", arg); return EINVAL; } filter_action = filter_priority; } else if (match_input("accept",arg)) { if (filter_action != filter_invalid) { printoutc(fd, "Invalid double action for filter"); } filter_action = filter_accept; } else if (match_input("reject",arg)) { if (filter_action != filter_invalid) { printoutc(fd, "Invalid double action for filter"); } filter_action = filter_reject; } else if (match_input("drop",arg)) { if (filter_action != filter_invalid) { printoutc(fd, "Invalid double action for filter"); } filter_action = filter_drop; } arg = strtok_r(NULL, " ", &nextargs); } if ((filter_action == filter_invalid) && (action == ACTION_ADD)) { printoutc(fd, "Error: an action is required for filter"); return EINVAL; } if (action == ACTION_ADD) { if (vder_filter_add(vif, proto, s_addr.s_addr, s_nm.s_addr, d_addr.s_addr, d_nm.s_addr, tos, sport, dport, filter_action, priority)) return errno; } else { if (vder_filter_del(vif, proto, s_addr.s_addr, s_nm.s_addr, d_addr.s_addr, d_nm.s_addr, tos, sport, dport)) return errno; } return 0; }
static int route(int fd,char *s) { char *nextargs = NULL, *arg; struct vder_route *ro; struct vder_iface *selected = NULL; struct in_addr temp_address, temp_netmask, temp_gateway; int metric = 1; enum command_action_enum action = -1; arg = strtok_r(s, " ", &nextargs); if(!arg) { /* No arguments */ ro = Router.routing_table; while(ro) { show_route(fd, ro); ro = ro->next; } return 0; } if ((!arg) || (strlen(arg) != 3) || ((strncmp(arg, "add", 3) != 0) && (strncmp(arg, "del", 3) != 0))) { printoutc(fd, "Invalid action \"%s\".", arg); return EINVAL; } if (strncmp(arg, "del", 3) == 0) action = ACTION_DELETE; else action = ACTION_ADD; arg = strtok_r(NULL, " ", &nextargs); if (!arg) { not_understood(fd, ""); return EINVAL; } if (match_input("default", arg)) { if (action == ACTION_ADD) action = ACTION_ADD_DEFAULT; if (action == ACTION_DELETE) { if (vder_route_del(0, 0, 1)) return errno; else return 0; } arg = strtok_r(NULL, " ", &nextargs); } if (!inet_aton(arg, &temp_address) || !is_unicast(temp_address.s_addr)) { printoutc(fd, "Invalid address \"%s\"", arg); return EINVAL; } if (action == ACTION_ADD_DEFAULT) { if (vder_route_add(0, 0, temp_address.s_addr, 1, NULL)) return errno; else return 0; } arg = strtok_r(NULL, " ", &nextargs); if (!arg) { printoutc(fd, "Error: parameter 'netmask' required."); return EINVAL; } if (!inet_aton(arg, &temp_netmask) || !is_netmask(temp_netmask.s_addr)) { printoutc(fd, "Invalid netmask \"%s\"", arg); return EINVAL; } arg = strtok_r(NULL, " ", &nextargs); while(arg) { if (match_input("via", arg)) { arg = strtok_r(NULL, " ", &nextargs); selected = select_interface(arg); if (!selected) return EINVAL; } else if (match_input("gw", arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!inet_aton(arg, &temp_gateway) || !is_unicast(temp_gateway.s_addr)) { printoutc(fd, "Invalid gateway \"%s\"", arg); return EINVAL; } } else if (match_input("metric", arg)) { arg = strtok_r(NULL, " ", &nextargs); metric = atoi(arg); if (metric < 1) { printoutc(fd, "Invalid metric \"%s\"", arg); return EINVAL; } } else { return EINVAL; } arg = strtok_r(NULL, " ", &nextargs); } if ((action == ACTION_DELETE) && (vder_route_del(temp_address.s_addr, temp_netmask.s_addr, metric))) { return errno; } else if ((action == ACTION_ADD) && (vder_route_add(temp_address.s_addr, temp_netmask.s_addr, temp_gateway.s_addr, metric, selected))) { return errno; } return 0; }
static int ifconfig(int fd,char *s) { char *nextargs = NULL, *arg; struct vder_iface *iface; arg = strtok_r(s, " ", &nextargs); if(!arg) { /* No arguments */ iface = Router.iflist; while(iface) { show_ifconfig(fd, iface); printoutc(fd, ""); iface = iface->next; } return 0; } else { struct vder_iface *selected; struct in_addr temp_address, temp_netmask; enum command_action_enum action = -1; selected = select_interface(arg); if (!selected) { printoutc(fd, "Interface %s not found.", arg); return ENOENT; } arg = strtok_r(NULL, " ", &nextargs); if (!arg) { show_ifconfig(fd, selected); return 0; } if ((!arg) || (strlen(arg) != 3) || ((strncmp(arg, "add", 3) != 0) && (strncmp(arg, "del", 3) != 0))) { printoutc(fd, "Invalid action \"%s\".", arg); return EINVAL; } if (strncmp(arg, "del", 3) == 0) action = ACTION_DELETE; else action = ACTION_ADD; arg = strtok_r(NULL, " ", &nextargs); if (!arg) { not_understood(fd, ""); return EINVAL; } if (match_input("dhcp", arg)) { temp_address.s_addr = (uint32_t)(-1); pthread_create(&selected->dhcpclient, 0, dhcp_client_loop, selected); } else if (!inet_aton(arg, &temp_address) || !is_unicast(temp_address.s_addr)) { printoutc(fd, "Invalid address \"%s\"", arg); return EINVAL; } arg = strtok_r(NULL, " ", &nextargs); if (!arg && (action == ACTION_ADD) && (temp_address.s_addr != (uint32_t)(-1))) { printoutc(fd, "Error: parameter 'netmask' required."); return EINVAL; } if ((action == ACTION_ADD) && (temp_address.s_addr != (uint32_t)(-1)) && (!inet_aton(arg, &temp_netmask) || !is_netmask(temp_netmask.s_addr))) { printoutc(fd, "Invalid netmask \"%s\"", arg); return EINVAL; } if (action == ACTION_ADD) { if (vder_iface_address_add(selected, temp_address.s_addr, temp_netmask.s_addr) != 0) return errno; } else { if (vder_iface_address_del(selected, temp_address.s_addr) != 0) return errno; } } return 0; }
static int dhcpd(int fd,char *s) { char *nextargs = NULL, *arg; struct vder_dhcpd_settings *dhcpd_settings; struct vder_iface *selected = NULL; struct in_addr temp_pool_start, temp_pool_end; enum command_action_enum action = -1; arg = strtok_r(s, " ", &nextargs); if(!arg) { printoutc(fd, "Error: arguments required"); return EINVAL; } if ((!arg) || (strlen(arg) < 4) || ((strncmp(arg, "start", 5) != 0) && (strncmp(arg, "stop", 4) != 0))) { printoutc(fd, "Invalid action \"%s\".", arg); return EINVAL; } if (strncmp(arg, "start", 5) == 0) action = ACTION_ADD; else action = ACTION_DELETE; arg = strtok_r(NULL, " ", &nextargs); if (!arg) { not_understood(fd, ""); return EINVAL; } if ((strlen(arg) < 4) || (strncmp(arg, "eth", 3)!= 0)) { printoutc(fd, "Invalid interface \"%s\".", arg); return EINVAL; } selected = select_interface(arg); if (!selected) return ENXIO; if (action == ACTION_ADD) { arg = strtok_r(NULL, " ", &nextargs); if (!arg) { not_understood(fd, ""); return EINVAL; } if (!inet_aton(arg, &temp_pool_start) || !is_unicast(temp_pool_start.s_addr)) { printoutc(fd, "Invalid pool start address \"%s\"", arg); return EINVAL; } arg = strtok_r(NULL, " ", &nextargs); if (!arg) { not_understood(fd, ""); return EINVAL; } if (!inet_aton(arg, &temp_pool_end) || !is_unicast(temp_pool_end.s_addr)) { printoutc(fd, "Invalid pool end address \"%s\"", arg); return EINVAL; } dhcpd_settings = malloc(sizeof(struct vder_dhcpd_settings)); if (!dhcpd_settings) return ENOMEM; dhcpd_settings->iface = selected; dhcpd_settings->my_ip = vder_get_right_localip(selected, temp_pool_start.s_addr); dhcpd_settings->netmask = vder_get_netmask(selected, dhcpd_settings->my_ip); dhcpd_settings->pool_start = temp_pool_start.s_addr; dhcpd_settings->pool_end = temp_pool_end.s_addr; dhcpd_settings->lease_time = DEFAULT_LEASE_TIME; dhcpd_settings->flags = 0; selected->dhcpd_started = 1; pthread_create(&selected->dhcpd, 0, dhcp_server_loop, dhcpd_settings); } else if (selected->dhcpd_started) { pthread_cancel(selected->dhcpd); selected->dhcpd_started = 0; } return 0; }