 |
|
| |
SYSCTLMIBINFO(3) |
FreeBSD Library Functions Manual |
SYSCTLMIBINFO(3) |
SYSCTLMIF_VERSION ,
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 ,
sysctlmif_mib ,
sysctlmif_freemib — sysctl
MIB-Tree API
library
“libsysctlmibinfo”
#include
<sys/types.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
#include <sysctlmibinfo.h>
#define SYSCTLMIF_VERSION
#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);
typedef int
(*sysctlmif_filterfunc_t) (struct
sysctlmif_object *object);
struct sysctlmif_list *
sysctlmif_filterlist (sysctlmif_filterfunc_t
filterfunc, unsigned int flags);
struct sysctlmif_list *
SYSCTLMIF_LIST (unsigned
int flags);
#define SYSCTLMIF_MAXDEPTH
struct sysctlmif_list *
sysctlmif_grouplist (int
*idstart, size_t idstartlen,
unsigned int flags, unsigned int
max_depth);
void
sysctlmif_freelist (struct
sysctlmif_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);
struct sysctlmif_list *
sysctlmif_mib (unsigned
int flags);
void
sysctlmif_freemib (struct
sysctlmif_list *mib);
The sysctlmibinfo library is an interface
to the kernel sysctl MIB-Tree. It implements wrappers around an undocumented
kernel interface to provide a more easy interface for exploring the sysctl
MIB and for getting the properties of an object, moreover it defines a
struct sysctlmif_object and provides a convenient API
to build data structures of sysctlmif_object; as it is
not designed to get and set object values, anyone wishing to do this should
see
sysctl(3).
An object is identified by an Object Identifier (OID), it is
represented by a pair int *id and
size_t idlevel, the level should be between 1 and
SYSCTLMIF_MAXIDLEVEL , see
BUGS.
Please refer to
sysctlmibinfo2(3)
for an improved and more efficient API on a new kernel interface.
SYSCTLMIF_VERSION is set to 1 to
differentiate between this library and
sysctlmibinfo2(3).
sysctlmif_nametoid ()
sets id and idlevel like the object with
name and
namelen.
sysctlmif_name (),
sysctlmif_desc ()
and
sysctlmif_label ()
set name and namelen,
desc and desclen,
label and labellen, like the
object with id and idlevel.
sysctlmif_nextleaf ()
and
sysctlmif_nextnode ()
set
nextid
and
nextidlevel
like the next leaf or internal node visited in a “Depth First
Traversal” of the object id and
idlevel.
sysctlmif_info ()
sets info and
infolen
like the object 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:
The previous functions seek the object with
id and idlevel or
name, then the property is copied into the buffer
(e.g., desc, label,
idnext, etc.). Before the call buflen (e.g.,
desclen, lebellen,
idnextlevel, etc.) gives the size of buffer, after a
successful call buflen gives the amount of data copied; the size of the
property can be determined with the NULL argument
for the buffer, the size will be returned in the location pointed to by
buflen. Note, the value of idnextlevel represents the
number of elements of idnext, not its size in
byte.
SYSCTLMIF_NAMELEN (),
SYSCTLMIF_DESCLEN ()
and
SYSCTLMIF_LABELLEN ()
set namelen,
desclen,
and
labellen
like the object with id and idlevel.
The sysctlmibinfo library defines a struct
for the info of an object:
SLIST_HEAD(sysctlmif_list, sysctlmif_object);
struct sysctlmif_object {
SLIST_ENTRY(sysctlmif_object) object_link;
int *id; /* array of idlevel entries */
size_t idlevel; /* between 1 and SYSCTLMIF_MAXIDLEVEL */
char *name; /* name in MIB notation */
char *desc; /* description */
char *label; /* aggregation label */
uint8_t type; /* defined in <sys/sysctl.h> */
uint32_t flags; /* defined in <sys/sysctl.h> */
char *fmt; /* format string */
struct sysctlmif_list *children; /* children list */
};
/*
* OR FLAGS: object fields to set,
* id and idlevel are always set,
* children list is set by sysctlmif_tree() and sysctlmif_mib().
*/
#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 */
and a list of objects, struct
sysctlmif_list, iterable by the SLIST macros, see
queue(3)
and EXAMPLES.
sysctlmif_object ()
returns a pointer to the allocated memory for a struct
sysctlmif_object, setting flags members, of the
object with id and idlevel. The
pointer can be passed to
sysctlmif_freeobject ()
to free the memory.
sysctlmif_filterlist ()
allocates memory for a SLIST of sysctlmif_object, setting
flags members, an object is added if
filterfunc returns 0 or is
NULL ; sysctlmif_filterlist ()
uses sysctlmif_nextnode () and object.children is not
set.
SYSCTLMIF_LIST ()
allocates memory and returns a SLIST of sysctlmif_object, setting
flags members, it is an alias for
sysctlmif_filterlist (NULL,
flags).
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. Note:
sysctlmif_grouplist () uses
sysctlmif_nextnode (), object.children is not set and
max_depth can be set to
SYSCTLMIF_MAXDEPTH .
sysctlmif_freelist ()
frees the allocated memory of list.
sysctlmif_tree ()
allocates memory for a tree of sysctlmif_object, setting
flags members, until max_depth and
returns a pointer to the root denoted by the entry with id
and idlevel. Note: max_depth can be set
to SYSCTLMIF_MAXDEPTH , object.children is set and
iterable by SLIST macros. The pointer can be passed to
sysctlmif_freetree ()
to free the memory.
sysctlmif_mib ()
allocates memory for a collection of trees, setting flags
members, and returns a list where the entries are the roots representing the
top-level objects,
sysctlmif_freemib ()
frees the allocated memory.
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 (),
sysctlmif_mib () functions return
NULL upon error or a pointer to allocated memory for
success.
Complete set of examples:
https://gitlab.com/alfix/sysctlmibinfo/tree/master/examples
If installed:
/usr/local/share/examples/sysctlmibinfo/
Example to print the Sound Driver objects:
struct sysctlmif_list *list;
struct sysctlmif_object *obj;
int id[2], i;
size_t idlevel = 2;
size_t namelen = strlen("hw.snd") + 1;
if ((sysctlmif_nametoid("hw.snd", namelen, id, &idlevel)) != 0)
return (1);
list = sysctlmif_grouplist(id, idlevel, SYSCTLMIF_FALL,
SYSCTLMIF_MAXDEPTH);
if (list == NULL)
return (1);
SLIST_FOREACH(obj, list, object_link) {
printf("OID:");
for(i = 0; i < obj->idlevel; i++)
printf(" %d", obj->id[i]);
printf("\n");
printf("name: %s\n", obj->name);
printf("descr: %s\n", obj->desc ? obj->desc : "");
printf("label: %s\n", obj->label ? obj->label : "");
printf("flags: %u\n", obj->flags);
printf("type: %u\n", obj->type);
printf("fmt: %s\n", obj->fmt);
printf("----------------------\n");
}
sysctlmif_freelist(list);
The sysctlmibinfo library first appeared
in FreeBSD 13.0.
sysctlmif_nextleaf () does not return an
object with the CTLFLAG_SKIP .
FreeBSD < 13,
sysctlmif_nextnode () does not return an object with
the CTLFLAG_SKIP flag and requires extra computation
in userspace because the kernel returns only the next leaf.
sysctlmif_desc () could set
desc to:
“” or NULL for an object without
description.
The undocumented interface does not support Capability Mode so the
kernel returns the properties of an object without considering
cap_enter(2),
CTLFLAG_CAPRD and
CTLFLAG_CAPWR .
sysctlmif_nametoid () cannot manage a name
expanded with an input for the object handler, e.g.,
“kern.proc.pid.1”; the kernel interface does not consider if
an object is a CTLTYPE_NODE with a defined
handler.
sysctlmif_name () could build a fake name
up to 10 digits depending on id, e.g.,
1.1.100.500.1000 → “kern.ostype.100.500.1000”, if no
object has the specified OID; properly the kernel interface does not check
if an object is a CTLTYPE_NODE with a defined
handler.
sysctlmif_object () is inefficient because
the kernel needs to find many times the same object to get all its
properties.
The kernel can store an object with an OID of
CTL_MAXNAME levels but the kernel undocumented
interface can handle an OID up to CTL_MAXNAME-2 ;
except sysctlmif_name (), this library could fail
with a false negative.
sysctlmif_nametoid () could return a wrong
OID if some level name has a NULL string, e.g.,
“security.jail.param.allow.mount.”.
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc.
|