Manual sysctlmibinfo(3)
Updated Post: alfonsosiciliano.gitlab.io/posts/2019-01-25-sysctlmibinfo.html
Please refer to the new Blog alfonsosiciliano.gitlab.io for updates.
sysctlmibinfo is an open source (2-Clause BSD License) library for FreeBSD. It provides an easy userland API to the kernel sysctl MIB Tree to get mib-entry information, to traverse the MIB and then to build quickly a custom sysctl(8) tool.
This post shows the manual page, for tutorial, examples and extra stuff:
wiki.freebsd.org/AlfonsoSiciliano/sysctlmibinfo.
SYSCTLMIBINFO(3) FreeBSD Library Functions Manual SYSCTLMIBINFO(3)
NAME
SYSCTLMIF_MAXIDLEVEL, sysctlmif_nametoid, sysctlmif_name,
SYSCTLMIF_NAMELEN, sysctlmif_desc, SYSCTLMIF_DESCLEN, sysctlmif_label,
SYSCTLMIF_LABELLEN, sysctlmif_info, SYSCTLMIF_INFOKIND,
SYSCTLMIF_INFOTYPE, SYSCTLMIF_INFOFLAGS, SYSCTLMIF_INFOFMT,
sysctlmif_nextnode, sysctlmif_nextleaf, sysctlmif_object,
sysctlmif_freeobject, sysctlmif_filterlist, SYSCTLMIF_LIST,
SYSCTLMIF_MAXDEPTH, sysctlmif_grouplist, sysctlmif_freelist,
sysctlmif_tree, sysctlmif_freetree - get sysctl mib information
LIBRARY
library "libsysctlmibinfo"
SYNOPSIS
#include <sys/types.h>
#include <sys/queue.h>
#include <sysctlmibinfo.h>
#define SYSCTLMIF_MAXIDLEVEL;
int
sysctlmif_nametoid(const char *name, size_t namelen, int *id,
size_t *idlevel);
int
sysctlmif_name(int *id, size_t idlevel, char *name, size_t *namelen);
int
SYSCTLMIF_NAMELEN(int *id, size_t idlevel, size_t *namelen);
int
sysctlmif_desc(int *id, size_t idlevel, char *desc, size_t *desclen);
int
SYSCTLMIF_DESCLEN(int *id, size_t idlevel, size_t *desclen);
int
sysctlmif_label(int *id, size_t idlevel, char *label, size_t *labellen);
int
SYSCTLMIF_LABELLEN(int *id, size_t idlevel, size_t *labellen);
int
sysctlmif_info(int *id, size_t idlevel, void *info, size_t *infolen);
uint32_t
SYSCTLMIF_INFOKIND(info);
uint8_t
SYSCTLMIF_INFOTYPE(info);
uint32_t
SYSCTLMIF_INFOFLAGS(info);
char *
SYSCTLMIF_INFOFMT(info);
int
sysctlmif_nextleaf(int *id, size_t idlevel, int *nextid,
size_t *nextidlevel);
int
sysctlmif_nextnode(int *id, size_t idlevel, int *nextid,
size_t *nextidlevel);
struct sysctlmif_object *
sysctlmif_object(int *id, size_t idlevel, unsigned int flags);
void
sysctlmif_freeobject(struct sysctlmif_object *object);
#define SYSCTLMIF_MAXDEPTH
struct sysctlmif_object_list *
sysctlmif_filterlist(sysctlmif_filterfunc_t *filterfunc,
unsigned int flags);
struct sysctlmif_object_list *
SYSCTLMIF_LIST(unsigned int flags);
struct sysctlmif_object_list *
sysctlmif_grouplist(int *idstart, size_t idstartlen, unsigned int flags,
unsigned int max_depth);
void
sysctlmif_freelist(struct sysctlmif_object_list *list);
struct sysctlmif_object *
sysctlmif_tree(int *id, size_t idlevel, unsigned int flags,
unsigned int max_depth);
void
sysctlmif_freetree(struct sysctlmif_object *node);
DESCRIPTION
The sysctlmibinfo library is an interface to the kernel sysctl mib.
It implements wrappers around undocumented "sysctl.*" kernel states to
get mib information and provides a convenient API to build a mib-entry,
entries-list and entries-tree in userspace; as it is not designed to get
and set entry values, anyone wishing to do this should see sysctl(3).
A mib-entry is identified by a pair int *id and size_t idlevel, the level
should be between 1 and SYSCTLMIF_MAXIDLEVEL, see sysctlmif_next().
sysctlmif_nametoid() sets id and idlevel like the entry with name and
namelen.
SYSCTLMIF_NAMELEN(), SYSCTLMIF_DESCLEN() and SYSCTLMIF_LABELLEN() set
namelen, desclen, and labellen like the entry with id and idlevel.
sysctlmif_name(), sysctlmif_desc() and sysctlmif_label() set name and
namelen, desc and desclen, label and labellen like the entry with id and
idlevel.
sysctlmif_info() sets info and infolen like the entry with id and
idlevel, info has the format: 3 bytes for flags, 1 byte for type and a
string for the "format string"; flags and type are defined in
<sys/sysctl.h>. Macros to deal with info:
SYSCTLMIF_INFOFLAGS(info) returns flags;
SYSCTLMIF_INFOTYPE(info) returns entry type;
SYSCTLMIF_INFOKIND(info) returns flags following by type;
SYSCTLMIF_INFOFMT(info) returns a pointer to the "format string".
sysctlmif_nextleaf() sets nextid and nextidlevel like the next-leaf-entry
of the entry with id and idlevel. sysctlmif_nextnode() sets nextid and
nextidlevel like the next-[node|leaf]-entry of the entry with id and
idlevel. Notes: nextid should have size SYSCTLMIF_MAXIDLEVEL and
nextidlevel should be set to SYSCTLMIF_MAXIDLEVEL before to call
sysctlmif_nextleaf() or sysctlmif_nextnode().
sysctlmif_object() returns a pointer to allocated memory for a struct
sysctlmif_object (setting flags members) of the entry with id and
idlevel. A mib userspace entry is defined:
/* 'struct sysctlmif_object': userspace mib entry definition */
SLIST_HEAD(sysctlmif_object_list, sysctlmif_object);
struct sysctlmif_object {
SLIST_ENTRY(sysctlmif_object) object_link;
int *id;
size_t idlevel; /* between 1 and SYSCTLMIF_MAXIDLEVEL */
char *name;
char *desc;
char *label; /* aggregation label */
uint8_t type; /* defined in <sys/sysctl.h> */
uint32_t flags; /* defined in <sys/sysctl.h> */
char *fmt; /* format string */
/* children is set by sysctlmif_tree() */
struct sysctlmif_object_list *children;
};
/*
* OR_FLAGS: object fields to set,
* .id and .idlevel are always set
* .children is default for sysctlmif_tree()
*/
#define SYSCTLMIF_FNAME 0x01 /* .name */
#define SYSCTLMIF_FDESC 0x02 /* .desc */
#define SYSCTLMIF_FLABEL 0x04 /* .label */
#define SYSCTLMIF_FTYPE 0x08 /* .type */
#define SYSCTLMIF_FFLAGS 0x10 /* .flags */
#define SYSCTLMIF_FFMT 0x20 /* .fmt */
#define SYSCTLMIF_FALL /* all */
SYSCTLMIF_LIST() allocates memory and returns a SLIST of sysctlmif_object
(setting flags members), it is an alias for sysctlmif_filterlist(NULL,
flags).
sysctlmif_filterlist() allocates memory for a SLIST of sysctlmif_object
(setting flags members), an object "o" is added if
int sysctlmif_filterfunc_t (struct sysctlmif_object *o)
returns 0 or filterfunc is NULL; notes: sysctlmif_filterlist() uses
sysctlmif_nextnode() and object.children is not set.
sysctlmif_grouplist() allocates memory and returns a SLIST of
sysctlmif_object (setting flags members) visited in a "Depth First
Traversal" until max_depth, id and idlevel denote the root. Notes:
sysctlmif_grouplist() uses sysctlmif_nextnode(), object.children is not
set and max_depth can be set to SYSCTLMIF_MAXDEPTH.
sysctlmif_tree() allocates memory for a tree of sysctlmif_object nodes
(setting flags members) until max_depth and returns a pointer to the
root: the entry with id and idlevel. Notes: max_depth can be set to
SYSCTLMIF_MAXDEPTH, object.children is set and iterable by SLIST macros.
sysctlmif_freeobject(), sysctlmif_freelist() and sysctlmif_freetree()
free allocated memory.
IMPLEMENTATION NOTES
sysctlmibinfo uses sysctl() syscall for wrapping 0.[1-6] entries defined
in kern_sysctl.c. The kernel returns only next leaf,
sysctlmif_nextnode() requires extra computation.
RETURN VALUES
The sysctlmif_nametoid(), SYSCTLMIF_NAMELEN(), sysctlmif_name(),
SYSCTLMIF_DESCLEN(), sysctlmif_desc(), SYSCTLMIF_LABELLEN(),
sysctlmif_label(), sysctlmif_info(), sysctlmif_nextnode(), and
sysctlmif_nextleaf() functions return the value 0 if successful;
otherwise the value -1 is returned and the global variable errno is set
to indicate the error.
The sysctlmif_object(), sysctlmif_filterlist(), SYSCTLMIF_LIST(),
sysctlmif_grouplist(), sysctlmif_tree() functions return NULL upon error
or a pointer to allocated memory for success.
EXAMPLES
Complete set of examples:
https://gitlab.com/alfix/sysctlmibinfo/tree/master/examples
SEE ALSO
queue(3), sysctl(3)
HISTORY
The sysctlmibinfo library first appeared in FreeBSD 13.0.
AUTHORS
sysctlmibinfo and this manual page were written by Alfonso S. Siciliano
<alf.siciliano@gmail.com>
BUGS
Problems from the kernel space:
sysctlmif_name() false positive.
sysctlmif_desc() could set desc to: "" or NULL for entries without
description.
FreeBSD 13.0-CURRENT January 29, 2019 FreeBSD 13.0-CURRENT