Example #1
0
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;
}
Example #2
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;
}
Example #3
0
/*
 * 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;
}
Example #4
0
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;
}
Example #5
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;
}
Example #6
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;

}
Example #7
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;
}