static int add_target(unsigned long ptr)
{
	int err;
	struct target_info info;

	if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0)
		return err;

	if (!(err = target_add(&info)))
		err = copy_to_user((void *) ptr, &info, sizeof(info));

	return err;
}
Exemple #2
0
static int add_target(unsigned long ptr)
{
	struct target_info info;
	int err;

	err = copy_from_user(&info, (void *) ptr, sizeof(info));
	if (err)
		return -EFAULT;

	err = target_add(&info);
	if (err < 0)
		return err;

	err = copy_to_user((void *) ptr, &info, sizeof(info));
	if (err)
		return -EFAULT;

	return 0;
}
Exemple #3
0
/*
 * Continiously probing multiple hosts using ICMP-ECHO. As packets are
 * received dots are printed on the screen. Hosts not responding before
 * next packet is due will get a questionmark in the display. The probing
 * stops when SIGINT is received.
 */
int
main(int argc, char *argv[])
{
	char buf[BUFSIZ];
	struct timeval tv;
	struct target *t;
	char *end;
	int i;
	int len;
	char ch;

#ifdef DO_SOCK_RAW
	/* Open RAW-socket and drop root-privs */
	fd4 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
	fd4errno = errno;
	fd6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
	fd6errno = errno;
	if (setuid(getuid()) < 0) {
		perror("setuid");
		exit(EX_OSERR);
	}
#else /* !DO_SOCK_RAW */
	fd4 = -1;
	fd4errno = EAFNOSUPPORT;
	fd6 = -1;
	fd6errno = EAFNOSUPPORT;
#endif /* DO_SOCK_RAW */

	/* Parse command line options */
	while ((ch = getopt(argc, argv, "46ABCTVahc:i:w:")) != -1) {
		switch(ch) {
		case '4':
			v4_flag = 1;
			v6_flag = 0;
			break;
		case '6':
			v4_flag = 0;
			v6_flag = 1;
			break;
		case 'a':
			a_flag++;
			break;
		case 'A':
			A_flag++;
			break;
		case 'B':
			B_flag = 1;
			break;
		case 'C':
			C_flag = 1;
			break;
		case 'c':
			c_count = strtol(optarg, &end, 10);
			if (*optarg != '\0' && *end != '\0')
				usage("Invalid count");
			break;
		case 'T':
			T_flag = 1;
			break;
		case 'i':
			i_interval = strtod(optarg, &end) * 1000;
			if (*optarg != '\0' && *end != '\0')
				usage("Invalid interval");
			if (i_interval < 1000 && getuid() != 0)
				usage("Dangerous interval");
			break;
		case 'w':
			w_width = strtol(optarg, &end, 10);
			if (*optarg != '\0' && *end != '\0')
				usage("Invalid width");
			if (w_width < 0)
				usage("Invalid width");
			break;
		case 'V':
			fprintf(stderr, "%s %s\n", "xping", version);
			return (0);
		case 'h':
			usage(NULL);
			/* NOTREACHED */
		default:
			usage(NULL);
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	tv_interval.tv_sec = i_interval / 1000;
	tv_interval.tv_usec = i_interval % 1000 * 1000;

	/* Prepare event system and inbound socket */
	ev_base = event_base_new();
	dns = evdns_base_new(ev_base, 1);
	probe_setup();

	/* Read targets from program arguments and/or stdin. */
	list = NULL;
	for (i=0; i<argc; i++) {
		if (target_add(argv[i]) < 0) {
			return 1;
		}
	}
	if (!isatty(STDIN_FILENO) || argc < 1) {
		while(fgets(buf, sizeof(buf), stdin) != NULL) {
			if ((end = strchr(buf, '#')) != NULL)
				*end = '\0';
			for (len = strlen(buf) - 1; len > 0; len--) {
				if (strchr(" \t\n", buf[len]) == NULL)
					break;
				buf[len] = '\0';
			}
			if (buf[0] == '#' || len < 1)
				continue;
			if (target_add(buf) < 0) {
				perror("malloc");
				return 1;
			}
		}
	}
	if (!isatty(STDOUT_FILENO)) {
		ui_init = report_init;
		ui_update = report_update;
		ui_cleanup = report_cleanup;
	}
	if (list == NULL) {
		usage("no arguments");
	}

	/* Initial scheduling with increasing delay, distributes
	 * transmissions across the interval and gives a cascading effect. */
	tv.tv_sec = 0;
	tv.tv_usec = 0;
	DL_FOREACH(list, t) {
		t->ev_write = event_new(ev_base, -1, 0, target_probe_sched, t);
		event_add(t->ev_write, &tv);
		tv.tv_usec += 100*1000; /* target spacing: 100ms */
		tv.tv_sec += (tv.tv_usec >= 1000000 ? 1 : 0);
		tv.tv_usec -= (tv.tv_usec >= 1000000 ? 1000000 : 0);
	}