Esempio n. 1
0
int
main(int argc, char *argv[])
{
	struct pollfd pfd[1];
	char *ep, *cp;
	int on = 1;
	int send_time = 180;	/* Default time, 180 seconds (3 minutes) */
	struct sockaddr_in m_sin;
	uid_t unpriv_uid;
	gid_t unpriv_gid;
	long tmp;
	time_t delta = 0;
	struct timeval next, now;

	if (getuid())
		errx(1, "not super user");

	run_as(&unpriv_uid, &unpriv_gid);

	argv++; argc--;
	while (argc > 0 && *argv[0] == '-') {
		if (strcmp(*argv, "-m") == 0) {
			if (argc > 1 && *(argv + 1)[0] != '-') {
				/* Argument has been given */
				argv++, argc--;
				multicast_mode = SCOPED_MULTICAST;
				tmp = strtol(*argv, &ep, 10);
				if (*ep != '\0' || tmp < INT_MIN || tmp > INT_MAX)
					errx(1, "invalid ttl: %s", *argv);
				multicast_scope = (int)tmp;
				if (multicast_scope > MAX_MULTICAST_SCOPE)
					errx(1, "ttl must not exceed %u",
					MAX_MULTICAST_SCOPE);
			}
			else multicast_mode = PER_INTERFACE_MULTICAST;
		} else if (strcmp(*argv, "-g") == 0) {
			if (argc > 1 && *(argv + 1)[0] != '-') {
				argv++, argc--;
				send_time = (int)strtol(*argv, &ep, 10);
				if (send_time <= 0)
					errx(1, "time must be greater than 0");

				if (ep[0] != '\0') {
					if (ep[1] != '\0')
						errx(1, "invalid argument: %s", *argv);
					if (*ep == 'M' || *ep == 'm') {
						/* Time in minutes. */
						send_time *= 60;
					} else
						errx(1, "invalid argument: %s", *argv);
				}

				if (send_time > 180)
					errx(1, "cannot be greater than 180 seconds (3 minutes)");
			} else
				errx(1, "missing argument");
		} else if (strcmp(*argv, "-i") == 0)
			insecure_mode = 1;
		else if (strcmp(*argv, "-l") == 0)
			quiet_mode = 1;
		else if (strcmp(*argv, "-p") == 0)
			iff_flag = 0;
		else
			usage();
		argv++, argc--;
	}
	if (argc > 0)
		usage();
#ifndef DEBUG
        struct pidfh *pfh = NULL;
        pfh = pidfile_open(NULL, 600, NULL);
	daemon(1, 0);
        pidfile_write(pfh);
#endif
	signal(SIGHUP, hup);
	openlog("rwhod", LOG_PID, LOG_DAEMON);
	sp = getservbyname("who", "udp");
	if (sp == NULL)
		quit("udp/who: unknown service", WITHOUT_ERRNO);

	if (chdir(_PATH_RWHODIR) < 0)
		quit(_PATH_RWHODIR, WITH_ERRNO);

	/*
	 * Establish host name as returned by system.
	 */
	if (gethostname(myname, sizeof(myname)) < 0)
		quit("gethostname", WITH_ERRNO);

	if ((cp = strchr(myname, '.')) != NULL)
		*cp = '\0';
	strlcpy(mywd.wd_hostname, myname, sizeof(mywd.wd_hostname));
	utmpf = open(_PATH_UTMP, O_RDONLY|O_CREAT, 0644);
	if (utmpf < 0)
		quit(_PATH_UTMP, WITH_ERRNO);

	getboottime();
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
		quit("socket", WITH_ERRNO);

	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0)
		quit("setsockopt SO_BROADCAST", WITH_ERRNO);

	memset(&m_sin, 0, sizeof(m_sin));
	m_sin.sin_len = sizeof(m_sin);
	m_sin.sin_family = AF_INET;
	m_sin.sin_port = sp->s_port;
	if (bind(s, (struct sockaddr *)&m_sin, sizeof(m_sin)) < 0)
		quit("bind", WITH_ERRNO);

	setgid(unpriv_gid);
	setgroups(1, &unpriv_gid);	/* XXX BOGUS groups[0] = egid */
	setuid(unpriv_uid);
	if (!configure(s))
		exit(1);

	if (!quiet_mode) {
		send_host_information();
		delta = send_time;
		gettimeofday(&now, NULL);
		timeadd(&now, delta, &next);
	}

	pfd[0].fd = s;
	pfd[0].events = POLLIN;
 
	for (;;) {
		int n;

		n = poll(pfd, 1, 1000);

		if (onsighup) {
			onsighup = 0;
			getboottime();
		}

		if (n == 1)
			handleread(s);
		if (!quiet_mode) {
			gettimeofday(&now, NULL);
			if (now.tv_sec > next.tv_sec) {
				send_host_information();
				timeadd(&now, delta, &next);
			}
		}
	}
}
Esempio n. 2
0
void
sender_process(void)
{
	int sendcount;
	double avenrun[3];
	time_t now;
	int i, cc, status;
	struct utmpx *ut;
	struct stat stb;
	struct neighbor *np;
	struct whoent *we, *wend;

	sendcount = 0;
	for (;;) {
		we = mywd.wd_we;
		now = time(NULL);
		if (sendcount % 10 == 0)
			getboottime(0);
		sendcount++;
		wend = &mywd.wd_we[1024 / sizeof(struct whoent)];
		setutxent();
		while ((ut = getutxent()) != NULL && we < wend) {
			if (ut->ut_type != USER_PROCESS)
				continue;
			strncpy(we->we_utmp.out_line, ut->ut_line,
			    sizeof(we->we_utmp.out_line));
			strncpy(we->we_utmp.out_name, ut->ut_user,
			    sizeof(we->we_utmp.out_name));
			we->we_utmp.out_time =
			    htonl(_time_to_time32(ut->ut_tv.tv_sec));
			we++;
		}
		endutxent();

		if (chdir(_PATH_DEV) < 0) {
			syslog(LOG_ERR, "chdir(%s): %m", _PATH_DEV);
			exit(1);
		}
		wend = we;
		for (we = mywd.wd_we; we < wend; we++) {
			if (stat(we->we_utmp.out_line, &stb) >= 0)
				we->we_idle = htonl(now - stb.st_atime);
			we++;
		}
		(void) getloadavg(avenrun,
		    sizeof(avenrun) / sizeof(avenrun[0]));
		for (i = 0; i < 3; i++)
			mywd.wd_loadav[i] = htonl((u_long)(avenrun[i] * 100));
		cc = (char *)wend - (char *)&mywd;
		mywd.wd_sendtime = htonl(_time_to_time32(time(NULL)));
		mywd.wd_vers = WHODVERSION;
		mywd.wd_type = WHODTYPE_STATUS;
		if (multicast_mode == SCOPED_MULTICAST) {
			(void) sendto(s, (char *)&mywd, cc, 0,
			    (struct sockaddr *)&multicast_addr,
			    sizeof(multicast_addr));
		} else {
			for (np = neighbors; np != NULL; np = np->n_next) {
				if (multicast_mode == PER_INTERFACE_MULTICAST &&
				    (np->n_flags & IFF_MULTICAST) != 0) {
					/*
					 * Select the outgoing interface for the
					 * multicast.
					 */
					if (setsockopt(s, IPPROTO_IP,
					    IP_MULTICAST_IF,
					    &(((struct sockaddr_in *)np->n_addr)->sin_addr),
					    sizeof(struct in_addr)) < 0) {
						syslog(LOG_ERR,
						    "setsockopt IP_MULTICAST_IF: %m");
						exit(1);
					}
					(void) sendto(s, (char *)&mywd, cc, 0,
					    (struct sockaddr *)&multicast_addr,
					    sizeof(multicast_addr));
				} else {
					(void) sendto(s, (char *)&mywd, cc, 0,
					    np->n_addr, np->n_addrlen);
				}
			}
		}
		if (chdir(_PATH_RWHODIR) < 0) {
			syslog(LOG_ERR, "chdir(%s): %m", _PATH_RWHODIR);
			exit(1);
		}
		if (waitpid(pid_child_receiver, &status, WNOHANG) ==
		    pid_child_receiver) {
			break;
		}
		sleep(SL_INTERVAL);
	}
}
Esempio n. 3
0
static int show_stat(struct seq_file *p, void *v)
{
	int i, j;
	unsigned long jif;
	cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
	cputime64_t guest, guest_nice;
	u64 sum = 0;
	u64 sum_softirq = 0;
	unsigned int per_softirq_sums[NR_SOFTIRQS] = {0};
	struct timespec boottime;

	user = nice = system = idle = iowait =
		irq = softirq = steal = cputime64_zero;
	guest = guest_nice = cputime64_zero;
	getboottime(&boottime);
	jif = boottime.tv_sec;

	for_each_possible_cpu(i) {
		user = cputime64_add(user, kstat_cpu(i).cpustat.user);
		nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);
		system = cputime64_add(system, kstat_cpu(i).cpustat.system);
		idle = cputime64_add(idle, get_idle_time(i));
		iowait = cputime64_add(iowait, get_iowait_time(i));
		irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);
		softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
		steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
		guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest);
		guest_nice = cputime64_add(guest_nice,
			kstat_cpu(i).cpustat.guest_nice);
		sum += kstat_cpu_irqs_sum(i);
		sum += arch_irq_stat_cpu(i);

		for (j = 0; j < NR_SOFTIRQS; j++) {
			unsigned int softirq_stat = kstat_softirqs_cpu(j, i);

			per_softirq_sums[j] += softirq_stat;
			sum_softirq += softirq_stat;
		}
	}
	sum += arch_irq_stat();

	seq_printf(p, "cpu  %llu %llu %llu %llu %llu %llu %llu %llu %llu "
		"%llu\n",
		(unsigned long long)cputime64_to_clock_t(user),
		(unsigned long long)cputime64_to_clock_t(nice),
		(unsigned long long)cputime64_to_clock_t(system),
		(unsigned long long)cputime64_to_clock_t(idle),
		(unsigned long long)cputime64_to_clock_t(iowait),
		(unsigned long long)cputime64_to_clock_t(irq),
		(unsigned long long)cputime64_to_clock_t(softirq),
		(unsigned long long)cputime64_to_clock_t(steal),
		(unsigned long long)cputime64_to_clock_t(guest),
		(unsigned long long)cputime64_to_clock_t(guest_nice));
	for_each_online_cpu(i) {
		/* Copy values here to work around gcc-2.95.3, gcc-2.96 */
		user = kstat_cpu(i).cpustat.user;
		nice = kstat_cpu(i).cpustat.nice;
		system = kstat_cpu(i).cpustat.system;
		idle = get_idle_time(i);
		iowait = get_iowait_time(i);
		irq = kstat_cpu(i).cpustat.irq;
		softirq = kstat_cpu(i).cpustat.softirq;
		steal = kstat_cpu(i).cpustat.steal;
		guest = kstat_cpu(i).cpustat.guest;
		guest_nice = kstat_cpu(i).cpustat.guest_nice;
		seq_printf(p,
			"cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu "
			"%llu\n",
			i,
			(unsigned long long)cputime64_to_clock_t(user),
			(unsigned long long)cputime64_to_clock_t(nice),
			(unsigned long long)cputime64_to_clock_t(system),
			(unsigned long long)cputime64_to_clock_t(idle),
			(unsigned long long)cputime64_to_clock_t(iowait),
			(unsigned long long)cputime64_to_clock_t(irq),
			(unsigned long long)cputime64_to_clock_t(softirq),
			(unsigned long long)cputime64_to_clock_t(steal),
			(unsigned long long)cputime64_to_clock_t(guest),
			(unsigned long long)cputime64_to_clock_t(guest_nice));
	}
	seq_printf(p, "intr %llu", (unsigned long long)sum);

	/* sum again ? it could be updated? */
	for_each_irq_nr(j)
		seq_printf(p, " %u", kstat_irqs(j));

	seq_printf(p,
		"\nctxt %llu\n"
		"btime %lu\n"
		"processes %lu\n"
		"procs_running %lu\n"
		"procs_blocked %lu\n",
		nr_context_switches(),
		(unsigned long)jif,
		total_forks,
		nr_running(),
		nr_iowait());

	seq_printf(p, "softirq %llu", (unsigned long long)sum_softirq);

	for (i = 0; i < NR_SOFTIRQS; i++)
		seq_printf(p, " %u", per_softirq_sums[i]);
	seq_putc(p, '\n');

	return 0;
}
Esempio n. 4
0
/*
 * This version of Berkeley's rwhod has been modified to use IP multicast
 * datagrams, under control of a new command-line option:
 *
 *	rwhod -m	causes rwhod to use IP multicast (instead of
 *			broadcast or unicast) on all interfaces that have
 *			the IFF_MULTICAST flag set in their "ifnet" structs
 *			(excluding the loopback interface).  The multicast
 *			reports are sent with a time-to-live of 1, to prevent
 *			forwarding beyond the directly-connected subnet(s).
 *
 *	rwhod -m <ttl>	causes rwhod to send IP multicast datagrams with a
 *			time-to-live of <ttl>, via a SINGLE interface rather
 *			than all interfaces.  <ttl> must be between 0 and
 *			MAX_MULTICAST_SCOPE, defined below.  Note that "-m 1"
 *			is different than "-m", in that "-m 1" specifies
 *			transmission on one interface only.
 *
 * When "-m" is used without a <ttl> argument, the program accepts multicast
 * rwhod reports from all multicast-capable interfaces.  If a <ttl> argument
 * is given, it accepts multicast reports from only one interface, the one
 * on which reports are sent (which may be controlled via the host's routing
 * table).  Regardless of the "-m" option, the program accepts broadcast or
 * unicast reports from all interfaces.  Thus, this program will hear the
 * reports of old, non-multicasting rwhods, but, if multicasting is used,
 * those old rwhods won't hear the reports generated by this program.
 *
 *                  -- Steve Deering, Stanford University, February 1989
 */
int
main(int argc, char *argv[])
{
	int on;
	char *cp;
	struct sockaddr_in soin;
	uid_t unpriv_uid;
	gid_t unpriv_gid;

	on = 1;
	if (getuid())
		errx(1, "not super user");

	run_as(&unpriv_uid, &unpriv_gid);

	argv++;
	argc--;
	while (argc > 0 && *argv[0] == '-') {
		if (strcmp(*argv, "-m") == 0) {
			if (argc > 1 && isdigit(*(argv + 1)[0])) {
				argv++;
				argc--;
				multicast_mode  = SCOPED_MULTICAST;
				multicast_scope = atoi(*argv);
				if (multicast_scope > MAX_MULTICAST_SCOPE) {
					errx(1, "ttl must not exceed %u",
					    MAX_MULTICAST_SCOPE);
				}
			} else {
				multicast_mode = PER_INTERFACE_MULTICAST;
			}
		} else if (strcmp(*argv, "-i") == 0) {
			insecure_mode = 1;
		} else if (strcmp(*argv, "-l") == 0) {
			quiet_mode = 1;
		} else if (strcmp(*argv, "-p") == 0) {
			iff_flag = 0;
		} else {
			usage();
		}
		argv++;
		argc--;
	}
	if (argc > 0)
		usage();
#ifndef DEBUG
	daemon(1, 0);
#endif
	(void) signal(SIGHUP, getboottime);
	openlog("rwhod", LOG_PID | LOG_NDELAY, LOG_DAEMON);
	sp = getservbyname("who", "udp");
	if (sp == NULL) {
		syslog(LOG_ERR, "who/udp: unknown service");
		exit(1);
	}
	if (chdir(_PATH_RWHODIR) < 0) {
		syslog(LOG_ERR, "%s: %m", _PATH_RWHODIR);
		exit(1);
	}
	/*
	 * Establish host name as returned by system.
	 */
	if (gethostname(myname, sizeof(myname) - 1) < 0) {
		syslog(LOG_ERR, "gethostname: %m");
		exit(1);
	}
	if ((cp = strchr(myname, '.')) != NULL)
		*cp = '\0';
	strlcpy(mywd.wd_hostname, myname, sizeof(mywd.wd_hostname));
	getboottime(0);
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		syslog(LOG_ERR, "socket: %m");
		exit(1);
	}
	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
		syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
		exit(1);
	}
	memset(&soin, 0, sizeof(soin));
	soin.sin_len = sizeof(soin);
	soin.sin_family = AF_INET;
	soin.sin_port = sp->s_port;
	if (bind(s, (struct sockaddr *)&soin, sizeof(soin)) < 0) {
		syslog(LOG_ERR, "bind: %m");
		exit(1);
	}
	if (setgid(unpriv_gid) != 0) {
		syslog(LOG_ERR, "setgid: %m");
		exit(1);
	}
	if (setgroups(1, &unpriv_gid) != 0) {	/* XXX BOGUS groups[0] = egid */
		syslog(LOG_ERR, "setgroups: %m");
		exit(1);
	}
	if (setuid(unpriv_uid) != 0) {
		syslog(LOG_ERR, "setuid: %m");
		exit(1);
	}
	if (!configure(s))
		exit(1);
	if (!quiet_mode) {
		pid_child_receiver = pdfork(&fdp, 0);
		if (pid_child_receiver == 0) {
			receiver_process();
		} else if (pid_child_receiver > 0) {
			sender_process();
		} else if (pid_child_receiver == -1) {
			if (errno == ENOSYS) {
				syslog(LOG_ERR,
				    "The pdfork(2) system call is not available; recompile the kernel with options PROCDESC");
			} else {
				syslog(LOG_ERR, "pdfork: %m");
			}
			exit(1);
		}
	} else {
		receiver_process();
	}
}
Esempio n. 5
0
static int show_stat(struct seq_file *p, void *v)
{
	int i, j;
	unsigned long jif;
	u64 user, nice, system, idle, iowait, irq, softirq, steal;
	u64 guest, guest_nice;
	u64 sum = 0;
	u64 sum_softirq = 0;
	unsigned int per_softirq_sums[NR_SOFTIRQS] = {0};
	struct timespec boottime;

	user = nice = system = idle = iowait =
		irq = softirq = steal = 0;
	guest = guest_nice = 0;
	getboottime(&boottime);
	jif = boottime.tv_sec;

	for_each_possible_cpu(i) {
		user += kcpustat_cpu(i).cpustat[CPUTIME_USER];
		nice += kcpustat_cpu(i).cpustat[CPUTIME_NICE];
		system += kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
		idle += get_idle_time(i);
		iowait += get_iowait_time(i);
		irq += kcpustat_cpu(i).cpustat[CPUTIME_IRQ];
		softirq += kcpustat_cpu(i).cpustat[CPUTIME_SOFTIRQ];
		steal += kcpustat_cpu(i).cpustat[CPUTIME_STEAL];
		guest += kcpustat_cpu(i).cpustat[CPUTIME_GUEST];
		guest_nice += kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE];
		sum += kstat_cpu_irqs_sum(i);
		sum += arch_irq_stat_cpu(i);

		for (j = 0; j < NR_SOFTIRQS; j++) {
			unsigned int softirq_stat = kstat_softirqs_cpu(j, i);

			per_softirq_sums[j] += softirq_stat;
			sum_softirq += softirq_stat;
		}
	}
	sum += arch_irq_stat();

	seq_puts(p, "cpu ");
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(user));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(nice));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(system));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(idle));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(iowait));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(irq));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(softirq));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(steal));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest_nice));
	seq_putc(p, '\n');

	for_each_online_cpu(i) {
		/* Copy values here to work around gcc-2.95.3, gcc-2.96 */
		user = kcpustat_cpu(i).cpustat[CPUTIME_USER];
		nice = kcpustat_cpu(i).cpustat[CPUTIME_NICE];
		system = kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
		idle = get_idle_time(i);
		iowait = get_iowait_time(i);
		irq = kcpustat_cpu(i).cpustat[CPUTIME_IRQ];
		softirq = kcpustat_cpu(i).cpustat[CPUTIME_SOFTIRQ];
		steal = kcpustat_cpu(i).cpustat[CPUTIME_STEAL];
		guest = kcpustat_cpu(i).cpustat[CPUTIME_GUEST];
		guest_nice = kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE];
		seq_printf(p, "cpu%d", i);
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(user));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(nice));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(system));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(idle));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(iowait));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(irq));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(softirq));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(steal));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest_nice));
		seq_putc(p, '\n');
	}
	seq_printf(p, "intr %llu", (unsigned long long)sum);

	/* sum again ? it could be updated? */
	for_each_irq_nr(j)
		seq_put_decimal_ull(p, ' ', kstat_irqs_usr(j));

	seq_printf(p,
		"\nctxt %llu\n"
		"btime %lu\n"
		"processes %lu\n"
		"procs_running %lu\n"
		"procs_blocked %lu\n",
		nr_context_switches(),
		(unsigned long)jif,
		total_forks,
		nr_running(),
		nr_iowait());

	seq_printf(p, "softirq %llu", (unsigned long long)sum_softirq);

	for (i = 0; i < NR_SOFTIRQS; i++)
		seq_put_decimal_ull(p, ' ', per_softirq_sums[i]);
	seq_putc(p, '\n');

	return 0;
}