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