sysctlinfo is an interface to explore the sysctl tree and to pass the properties of the nodes to the userland, this post displays the manuals (sysctlinfo.4 and sysctlinfo.3), for an introduction, examples and FAQ: http://gitlab.com/alfix/sysctlinfo.

Legal notice: FreeBSD is a registered trademark of the FreeBSD Foundation.

man 4 sysctlinfo

SYSCTLINFO(4)          FreeBSD Kernel Interfaces Manual          SYSCTLINFO(4)

NAME
     sysctlinfo - a sysctl(3) MIB for getting info about the sysctl tree

SYNOPSIS
     sysctl sysctl.entryfakename
     sysctl sysctl.entryname
     sysctl sysctl.entrydesc
     sysctl sysctl.entrylabel
     sysctl sysctl.entrykind
     sysctl sysctl.entryfmt
     sysctl sysctl.entrynextnode
     sysctl sysctl.entrynextleaf
     sysctl sysctl.entryallinfo
     sysctl sysctl.entryallinfo_withnextnode
     sysctl sysctl.entryallinfo_withnextleaf
     sysctl sysctl.entryfakeidbyname
     sysctl sysctl.entryidbyname
     sysctl sysctl.entrydescbyname
     sysctl sysctl.entrylabelbyname
     sysctl sysctl.entrykindbyname
     sysctl sysctl.entryfmtbyname
     sysctl sysctl.entryallinfobyname
     sysctl sysctl.entryallinfobyname_withnextnode
     sysctl sysctl.entryallinfobyname_withnextleaf

DESCRIPTION
     The sysctlinfo interface explores the sysctl tree to pass the info of the
     nodes to userland, it should be used via sysctlinfo(3).

SEE ALSO
     sysctl(3), sysctlinfo(3)

HISTORY
     The sysctlinfo interface first appeared in FreeBSD 13.0.

AUTHORS
     The sysctlinfo interface was written by Alfonso S. Siciliano
     <alf.siciliano@gmail.com>

FreeBSD 13.0-CURRENT            August 2, 2019            FreeBSD 13.0-CURRENT

man 3 sysctlinfo

SYSCTLINFO(3)          FreeBSD Library Functions Manual          SYSCTLINFO(3)

NAME
     SYSCTLINFO SYSCTLINFO_BYNAME SYSCTLINFO_HELPER_ALL
     SYSCTLINFO_HELPER_ALLIWITHNEXT SYSCTLINFO_HELPER_ALLWITHNEXTNAME -
     Interface for getting info about the sysctl tree

SYNOPSIS
     #include <sys/types.h>
     #include <sys/sysctl.h>
     #include <sysctlinfo.h>

     #define ENTRYFAKENAME
     #define ENTRYNAME
     #define ENTRYDESC
     #define ENTRYLABEL
     #define ENTRYKIND
     #define ENTRYFMT
     #define ENTRYNEXTNODE
     #define ENTRYNEXTLEAF
     #define ENTRYALLINFO
     #define ENTRYALLINFO_WITHNEXTNODE
     #define ENTRYALLINFO_WITHNEXTLEAF
     #define ENTRYIDBYNAME
     #define ENTRYFAKEIDBYNAME
     #define ENTRYDESCBYNAME
     #define ENTRYLABELBYNAME
     #define ENTRYKINDBYNAME
     #define ENTRYFMTBYNAME
     #define ENTRYALLINFOBYNAME
     #define ENTRYALLINFOBYNAME_WITHNEXTNODE
     #define ENTRYALLINFOBYNAME_WITHNEXTLEAF

     int
     SYSCTLINFO(int *id, size_t idlevel, int prop[2], void *buf,
         size_t *buflen);

     int
     SYSCTLINFO_BYNAME(char *name, int prop[2], void *buf, size_t *buflen);

     void
     SYSCTLINFO_HELPER_ALL(void *buf, size_t idlevel, int *id, char *namep,
         char *descrp, unsigned int kind, char *fmtp, char *labelp);

     void
     SYSCTLINFO_HELPER_ALLWITHNEXT(void *buf, size_t idlevel, int *id,
         char *namep, char *descrp, unsigned int kind, char *fmtp,
         char *labelp, size_t idnextlevel, int *idnext);

     void
     SYSCTLINFO_HELPER_ALLWITHNEXTNAME(void *buf, size_t idlevel, int *id,
         char *namep, char *descrp, unsigned int kind, char *fmtp,
         char *labelp, char *namenextp);

DESCRIPTION
     Macros to wrap the sysctlinfo(4) interface to explore the sysctl tree and
     to get info about the nodes.  SYSCTLINFO() and SYSCLINFO_BYNAME() seek
     the node with id / idlevel or name, then the information specified by
     prop is copied into the buffer buf.  Before the call buflen gives the
     size of buf, after a successful call buflen gives the amount of data
     copied; the size of the info can be determined with the NULL argument for
     buf, the size will be returned in the location pointed to by buflen.  The
     value of prop[0] should be CTL_SYSCTL and prop[1] can specify the desired
     info, the possible values are listed later.

     SYSCTLINFO() accepts an array id of idlevel elements (between 1 and
     CTL_MAXNAME) and the following prop[1]:

     ENTRYFAKENAME
             if the node exists buf is set like a string with its name,
             otherwise sysctlinfo build a name depending on the id, e.g., with
             an id [1.1.100.500.1000] the name is "kern.ostype.100.500.1000".

     ENTRYNAME, ENTRYDESC, ENTRYLABEL and ENTRYFMT
             set buf like a string with the name, description, label and
             format, respectively.

     ENTRYKIND
             sets buf like an unsigned int with the kind of the node, its
             format is: 3 bytes for flags and 1 byte for type, they are
             defined in <sys/sysctl.h>.

     ENTRYNEXTNODE and ENTRYNEXTLEAF
             buf is set like an integer array with the id of the next
             node/leaf of a Depth-First Traversal, the next level is "buflen /
             sizeof(int)" to be consistent with the acceptable level range.

     ENTRYALLINFO
             sets the buf with all the info of the node, it should be passed
             to the helper macro SYSCTLINFO_HELPER_ALL(), if description,
             format or label is NULL, descp, fmtp or labep is set to ""
             respectively.

     ENTRYALLINFO_WITHNEXTNODE and ENTRYALLINFO_WITHNEXTLEAF
             set all the info of the node like SYSCTLINFO_ALLINFO with the
             next node/leaf, buf should be passed to
             SYSCTLINFO_HELPER_ALLWITHNEXT(), if the node has not a next
             idnextlevel is set to 0.

     SYSCTLINFO_BYNAME() accepts the following prop[1]:

     ENTRYFAKEIDBYNAME and ENTRYIDBYNAME
             buf is set like an integer array with the id of the node, the
             level is "buflen / sizeof(int)".  ENTRYFAKEIDBYNAME does not set
             the last level if its last level name is "", e.g., "n1.n2.n3."
             the id array is set to [1.2.3].

     ENTRYDESCBYNAME, ENTRYLABELBYNAME and ENTRYFMTBYNAME
             set buf like a string with the description, label and format
             respectively.

     ENTRYKINDBYNAME
             kind of an node, see ENTRYKIND.

     ENTRYALLINFOBYNAME
             sets the buf with all the info of the node, it should be passed
             to the helper macro SYSCTLINFO_HELPER_ALL(), if description,
             format or label is NULL, descp, fmtp or labep is set to ""
             respectively.

     ENTRYALLINFOBYNAME_WITHNEXTNODE and ENTRYALLINFOBYNAME_WITHNEXTLEAF
             set all the info of the node like SYSCTLINFO_ALLINFOBYNAME with
             the next node/leaf, buf should be passed to
             SYSCTLINFO_HELPER_ALLWITHNEXTNAME(), if the node has not a next
             node/leaf nextnamep is set to "".

IMPLEMENTATION NOTES
     The kernel provides an undocumented interface for the info of the sysctl
     tree, obviously sysctlinfo and the kernel interface can coexist.

     In "capability mode", see cap_enter(2), sysctlinfo checks if the node has
     the CTLFLAG_CAPRD or CTLFLAG_CAPWR flag before to return its info;
     sysctl(3) will check the "capability permission" to get or set a value.
     ENTRYFAKENAME has no capability check for compatibility with the kernel.
     ENTRYNEXTNODE and ENTRYNEXTLEAF check never the capability flags to
     traverse the tree also in capability mode.

     SYSCTLINFO() and SYSCTLINFO_BYNAME() seek the node with the id / idlevel
     or with the name then they share the same code.

RETURN VALUES
     The SYSCTLINFO() and SYSCTLINFO_BYNAME() functions return the value 0 if
     successful; otherwise the value -1 is returned and the global variable
     errno is set to indicate the error.

EXAMPLES
     If installed:
           /usr/local/share/examples/sysctlinfo/

     Example to visit the sysctl tree:

           int id[CTL_MAXNAME], *idp_unused, *idnextp;
           size_t idlevel, idnextlevel, buflen, i;
           char buf[BUFSIZE], *namep, *descrp, *fmtp, *labelp;
           unsigned int kind;
           int prop[2] = { CTL_SYSCTL, ENTRYALLINFO_WITHNEXTNODE };

           id[0]=0;
           idlevel=1;

           for (;;) {
                   for (i = 0; i < idlevel; i++)
                           printf("%d%c", id[i], i+1 < idlevel ? '.' : '\n');

                   buflen = BUFSIZE;
                   if(SYSCTLINFO(id, idlevel, prop, buf, &buflen) != 0) {
                           err(1, "ENTRYALLINFO_WITHNEXTNODE");

                   SYSCTLINFO_HELPER_ALLWITHNEXT(buf, idlevel, idp_unused, namep, descrp,
                                                 kind, fmtp, labelp, idnextlevel, idnextp);

                   printf("name: %s\n", namep);
                   printf("description: %s\n", descrp);
                   printf("label: %s\n", labelp);
                   printf("kind: %u\n", kind );
                   printf("flags: %u\n", kind & 0xfffffff0 );
                   printf("type: %u\n", kind & CTLTYPE );
                   printf("fmt: %s\n", fmtp);
                   printf("--------------------------------------\n");

                   if (idnextlevel < 1)
                           break;

                   memcpy(id, idnextp, idnextlevel * sizeof(int));
                   idlevel = idnextlevel;
           }

ERRORS
     The following errors may be reported:

     [ECAPMODE]         The node has not the CTLFLAG_CAPRD or CTLFLAG_CAPWR
                        flag in capability mode.

     [EINVAL]           name has more than CTL_MAXNAME levels.

     [EINVAL]           idlevel is either greater CTL_MAXNAME, equal to zero
                        or is not an integer.

     [ENAMETOOLONG]     name is >= MAXPATHLEN.

     [ENOATTR]          The node exists but its info is NULL.

     [ENOENT]           The node does not exist.

SEE ALSO
     cap_enter(2), sysctl(3), sysctlinfo(4)

HISTORY
     The sysctlinfo interface first appeared in FreeBSD 13.0.

AUTHORS
     The sysctlinfo interface was written by Alfonso S. Siciliano
     <alf.siciliano@gmail.com>

FreeBSD 13.0-CURRENT          September 20, 2019          FreeBSD 13.0-CURRENT