Subject: sysinfo(2) (was Re: pidentd)
To: None <tech-net@netbsd.org>
From: Aidan Cully <aidan@kublai.com>
List: tech-net
Date: 04/07/2000 12:05:17
On Fri, Apr 07, 2000 at 01:57:35AM -0400, der Mouse wrote:
> It does have its problems, certainly.  sysctl would be better except
> there's no obvious way that I can see to pass the port numbers in so as
> to get the uid back out.

I've been thinking for a while about a 'sysinfo' syscall, which would
behave quite a bit like using sysctl() to read values from the kernel,
but with the addition of a 'flags/flaglen' argument pair for allowing
the kernel to do a lot of the filtering on the data before it goes to
userland...  I haven't done anything with it, because I couldn't think
of any major advantages of it over using sysctl().  Maybe it would be
well suited to this function, though?

struct sysinfo_flag {
	int sif_name;
	union {
		int sifa_int;
		void *sifa_ptr;
	} sif_arg;
};

int sysinfo __P((int *name, u_int namelen,
    struct sysinfo_flag *flags, u_int flaglen,
    void *dest, size_t *destlenp));

int ident_name[] = {
	SI_KERN,
	SIK_NET,
	SIKN_TABLE
};

uid_t
ident_run(struct sockaddr_in *from, struct sockaddr_in *to)
{
	struct sysinfo_net net_table;
	struct sysinfo_flags ident_flags[2];
	int ret;
	size_t size;

	ident_flags[0].sif_name = SIKN_FROM_ADDR;
	ident_flags[0].sif_arg.sifa_ptr = from;
	ident_flags[0].sif_name = SIKN_TO_ADDR;
	ident_flags[1].sif_arg.sifa_ptr = to;
	size = 1;
	ret = sysinfo(ident_name, 3, ident_flags, 2, &net_table, &size);
	if (size > 1) {
		errx(1, "More than one connection with same source/dest.");
	} else if (size <= 0) {
		return ((uid_t) -1);
	}
	/* size == 1 */
	/* net_table now contains all the info the kernel wanted to give
	 * us about the net connection from 'from' and to 'to'. */
	return (net_table.perm.uid);
}

I was thinking about it as a general replacement for anything that used
libkvm against a live kernel.  Most of the motivation was in those
periodic 'proc size mismatch'es that /bin/ps gives when upgrading the
kernel, but done a bit differently sysctl() could avoid those as well.

--aidan