Sysctl variables are laid out in a hierarchical fashion. As an example let's decompose net.inet.tcp.sendspace 'net' is the root of the network sysctl variables, 'net.inet' is the root of the inter-networking sysctl variables, 'net.inet.tcp' is the root of sysctl variables pertaining to TCP and 'net.inet.tcp.sendspace' is a child node that defines the amount of send buffer space available to a TCP connection.
First, command line stuff:
# look at the value % sysctl net.inet.tcp.sendspace net.inet.tcp.sendspace: 32768 # get a description of the value with the -d flag % sysctl -d kern.ipc.maxsockbuf kern.ipc.maxsockbuf: Maximum socket buffer size # change the value # (the linux man page for sysctl recommends using -w flag # when writing variables but no explanation) % sysctl net.inet.tcp.sendspace=1048576 32768 -> 1048576 # search for a value (in the net.inet.tcp tree) % sysctl -a | grep net.inet.tcp ... list of values ...
Now, let's say we want to write a program to actually read these values in a C program. One may want to do this to read a struct, whose values cannot be easily read using the command line tool, or to generate a data file for later analysis. Start with "man -S3 sysctl" on FreeBSD.
// which should give you something like this... #include <sys/types.h> #include <sys/sysctl.h> int sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen);That's great, perhaps usage would be more helpful, keep in mind this works for simple data types (int, long, float) as well as structs
// let's say you actually wanted some value, say net.inet.tcp.sendspace int sendspace, len; len = sizeof(int); sysctlbyname("net.inet.tcp.sendspace", &sendspace, &len, NULL, 0); // or for a struct struct tcpstat tcpstat; int stat_len; stat_len = sizeof(stat_len); sysctlbyname("net.inet.tcp.stats", &tcpstat, &stat_len, NULL, 0);Last but not least, let's say you actually wanted to add your own sysctl variables into a kernel you might be compiling (you dashing hero you). For example sake, let's say you are implementing alternative congestion algorithms for TCP and wanted to switch between them without reloading a kernel. You might want to add the sysctl variable net.inet.tcp.congestion and set it to change the congestion algorithm used.
u_int tcp_custom_congestion = 2; SYSCTL_UINT(_net_inet_tcp_, OID_AUTO, congestion, CTLFLAG_RW, &tcp_custom_congestion, 0, "which custom TCP congestion algorithm to use at run-time");Which would then give you the sysctl variable
net.inet.tcp.congestionfor your usage initialized to 2. You need to shove these lines into some kernel code, probably where you'll remember, and in the scope at the point of usage, recompile, reboot, then use the command line sysctl tool to verify it was added.