Subject: Reading sysctl values in the kernel
To: None <tech-kern@netbsd.org>
From: Alan Ritter <rittera@cc.wwu.edu>
List: tech-kern
Date: 07/23/2005 20:37:20
Hello everyone,

I'm trying to port the FreeBSD NDIS driver to NetBSD, and right now I'm
having a bit of trouble figuring out some stuff to do with sysctl's
(FreeBSD's NDIS driver uses sysctl nodes to emulate the Windows registry).
 I've gotten all of the registry entries from the .inf file entered into
sysctl nodes using sysctl_createv() (man 9 sysctl), and they seem to be in
there just fine, since I can see a bunch of stuff from the .inf file from
typing "sysctl -A".

My problem is that I'm having trouble figuring out how to retrieve a
"struct sysctlnode" based on it's name.  It seems like the way to do this
from a user program would be sysctlbyname() (man 3 sysctl), but this can't
be used inside the kernel.  From reading man 9 sysctl I get the impression
that sysctl_dispatch() should be used to look up a node, but I haven't
gotten it to work yet.  I'm guessing that the sysctl dispatch function
works sort of the same way as sysctl(3), as sysctl() is implemented using
sysctl_dispatch() (in sys/kern/kern_sysctl.c).  Anyway, here's a general
outline of what I'm trying, I'm not sure that it makes any sense, but I
thought it might help demonstrate my lack of understanding.

struct sysctlnode node;
int len;
int error;
char buf[256];
int mib[2];

memset(&node, 0, sizeof(node));
node.sysctl_flags = SYSCTL_VERSION;
mib[0] = sc->ndis_sysctl_mib;     /* the ndis subtree */
mib[1] = CTL_QUERY;
strcpy(node.sysctl_name, keystr);
node.sysctl_data = buf;
len = sizeof(node);

sysctl_lock(curlwp, &node, len);
error = sysctl_dispatch(&mib[0], 2, &node, &len, &node,
                        len, &mib[0], curlwp, NULL);
sysctl_unlock(curlwp);

Thanks :-)