Blame agent/auto_nlist.c

Packit fcad23
#include <net-snmp/net-snmp-config.h>
Packit fcad23
Packit fcad23
#ifdef NETSNMP_CAN_USE_NLIST
Packit fcad23
#if HAVE_STRING_H
Packit fcad23
#include <string.h>
Packit fcad23
#else
Packit fcad23
#include <strings.h>
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#if HAVE_STDLIB_H
Packit fcad23
#include <stdlib.h>
Packit fcad23
#endif
Packit fcad23
#include <stdio.h>
Packit fcad23
#include <errno.h>
Packit fcad23
#include <fcntl.h>
Packit fcad23
#include <netinet/in.h>
Packit fcad23
#ifdef HAVE_NLIST_H
Packit fcad23
#include <nlist.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_KVM_H
Packit fcad23
#include <kvm.h>
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#include <net-snmp/agent/auto_nlist.h>
Packit fcad23
#include "autonlist.h"
Packit fcad23
#include "kernel.h"
Packit fcad23
Packit fcad23
#include <net-snmp/net-snmp-includes.h>
Packit fcad23
#include <net-snmp/agent/ds_agent.h>
Packit fcad23
Packit fcad23
struct autonlist *nlists = 0;
Packit fcad23
static void     init_nlist(struct nlist *);
Packit fcad23
Packit fcad23
long
Packit fcad23
auto_nlist_value(const char *string)
Packit fcad23
{
Packit fcad23
    struct autonlist **ptr, *it = 0;
Packit fcad23
    int             cmp;
Packit fcad23
Packit fcad23
    if (string == 0)
Packit fcad23
        return 0;
Packit fcad23
Packit fcad23
    ptr = &nlists;
Packit fcad23
    while (*ptr != 0 && it == 0) {
Packit fcad23
        cmp = strcmp((*ptr)->symbol, string);
Packit fcad23
        if (cmp == 0)
Packit fcad23
            it = *ptr;
Packit fcad23
        else if (cmp < 0) {
Packit fcad23
            ptr = &((*ptr)->left);
Packit fcad23
        } else {
Packit fcad23
            ptr = &((*ptr)->right);
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
    if (*ptr == 0) {
Packit fcad23
#if !(defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7))
Packit fcad23
        static char *n_name = NULL;
Packit fcad23
#endif
Packit fcad23
        *ptr = (struct autonlist *) malloc(sizeof(struct autonlist));
Packit fcad23
        memset(*ptr, 0, sizeof(struct autonlist));
Packit fcad23
        it = *ptr;
Packit fcad23
        it->left = 0;
Packit fcad23
        it->right = 0;
Packit fcad23
        it->symbol = (char *) malloc(strlen(string) + 1);
Packit fcad23
        strcpy(it->symbol, string);
Packit fcad23
        /*
Packit fcad23
         * allocate an extra byte for inclusion of a preceding '_' later 
Packit fcad23
         */
Packit fcad23
        it->nl[0].n_name = (char *) malloc(strlen(string) + 2);
Packit fcad23
#if defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
Packit fcad23
        strcpy(it->nl[0].n_name, string);
Packit fcad23
        it->nl[0].n_name[strlen(string)+1] = '\0';
Packit fcad23
#elif defined(freebsd9)
Packit fcad23
        sprintf(__DECONST(char*, it->nl[0].n_name), "_%s", string);
Packit fcad23
#else
Packit fcad23
Packit fcad23
        if (n_name != NULL)
Packit fcad23
            free(n_name);
Packit fcad23
Packit fcad23
        n_name = malloc(strlen(string) + 2);
Packit fcad23
        if (n_name == NULL) {
Packit fcad23
            snmp_log(LOG_ERR, "nlist err: failed to allocate memory");
Packit fcad23
            return (-1);
Packit fcad23
        }
Packit fcad23
        snprintf(n_name, strlen(string) + 2, "_%s", string);
Packit fcad23
        it->nl[0].n_name = (const char*)n_name;
Packit fcad23
#endif
Packit fcad23
        it->nl[1].n_name = 0;
Packit fcad23
        init_nlist(it->nl);
Packit fcad23
#if !(defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7) || \
Packit fcad23
                    defined(netbsd1) || defined(dragonfly))
Packit fcad23
        if (it->nl[0].n_type == 0) {
Packit fcad23
#if defined(freebsd9)
Packit fcad23
            strcpy(__DECONST(char*, it->nl[0].n_name), string);
Packit fcad23
            __DECONST(char*, it->nl[0].n_name)[strlen(string)+1] = '\0';
Packit fcad23
#else
Packit fcad23
            static char *n_name2 = NULL;
Packit fcad23
Packit fcad23
            if (n_name2 != NULL)
Packit fcad23
                free(n_name2);
Packit fcad23
Packit fcad23
            n_name2 = malloc(strlen(string) + 1);
Packit fcad23
            if (n_name2 == NULL) {
Packit fcad23
                snmp_log(LOG_ERR, "nlist err: failed to allocate memory");
Packit fcad23
                return (-1);
Packit fcad23
            }
Packit fcad23
            strcpy(n_name2, string);
Packit fcad23
            it->nl[0].n_name = (const char*)n_name2;
Packit fcad23
#endif
Packit fcad23
            init_nlist(it->nl);
Packit fcad23
        }
Packit fcad23
#endif
Packit fcad23
        if (it->nl[0].n_type == 0) {
Packit fcad23
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
Packit fcad23
                snmp_log(LOG_ERR, "nlist err: neither %s nor _%s found.\n",
Packit fcad23
                         string, string);
Packit fcad23
	    }
Packit fcad23
            return (-1);
Packit fcad23
        } else {
Packit fcad23
            DEBUGMSGTL(("auto_nlist:auto_nlist_value",
Packit fcad23
			"found symbol %s at %lx.\n",
Packit fcad23
                        it->symbol, it->nl[0].n_value));
Packit fcad23
            return (it->nl[0].n_value);
Packit fcad23
        }
Packit fcad23
    } else
Packit fcad23
        return (it->nl[0].n_value);
Packit fcad23
}
Packit fcad23
Packit fcad23
int
Packit fcad23
auto_nlist(const char *string, char *var, size_t size)
Packit fcad23
{
Packit fcad23
    long            result;
Packit fcad23
    int             ret;
Packit fcad23
    result = auto_nlist_value(string);
Packit fcad23
    if (result != -1) {
Packit fcad23
        if (var != NULL) {
Packit fcad23
            ret = klookup(result, var, size);
Packit fcad23
            if (!ret)
Packit fcad23
                snmp_log(LOG_ERR,
Packit fcad23
                         "auto_nlist failed on %s at location %lx\n",
Packit fcad23
                         string, result);
Packit fcad23
            return ret;
Packit fcad23
        } else
Packit fcad23
            return 1;
Packit fcad23
    }
Packit fcad23
    return 0;
Packit fcad23
}
Packit fcad23
Packit fcad23
static void
Packit fcad23
init_nlist(struct nlist nl[])
Packit fcad23
{
Packit fcad23
    int             ret;
Packit fcad23
#if HAVE_KVM_OPENFILES
Packit fcad23
    kvm_t          *kernel;
Packit fcad23
    char            kvm_errbuf[4096];
Packit fcad23
Packit fcad23
    if ((kernel = kvm_openfiles(KERNEL_LOC, NULL, NULL, O_RDONLY, kvm_errbuf))
Packit fcad23
	== NULL) {
Packit fcad23
        if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				   NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
Packit fcad23
            return;
Packit fcad23
	} else {
Packit fcad23
            snmp_log_perror("kvm_openfiles");
Packit fcad23
            snmp_log(LOG_ERR, "kvm_openfiles: %s\n", kvm_errbuf);
Packit fcad23
            exit(1);
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
    if ((ret = kvm_nlist(kernel, nl)) == -1) {
Packit fcad23
        if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				   NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
Packit fcad23
            return;
Packit fcad23
	} else {
Packit fcad23
            snmp_log_perror("kvm_nlist");
Packit fcad23
            exit(1);
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
    kvm_close(kernel);
Packit fcad23
#else                           /* ! HAVE_KVM_OPENFILES */
Packit fcad23
#if (defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)) && defined(HAVE_KNLIST)
Packit fcad23
    if (knlist(nl, 1, sizeof(struct nlist)) == -1) {
Packit fcad23
        DEBUGMSGTL(("auto_nlist:init_nlist", "knlist failed on symbol:  %s\n",
Packit fcad23
                    nl[0].n_name));
Packit fcad23
        if (errno == EFAULT) {
Packit fcad23
            nl[0].n_type = 0;
Packit fcad23
            nl[0].n_value = 0;
Packit fcad23
        } else {
Packit fcad23
            snmp_log_perror("knlist");
Packit fcad23
            if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				       NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
Packit fcad23
                return;
Packit fcad23
	    } else {
Packit fcad23
                exit(1);
Packit fcad23
	    }
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
#else
Packit fcad23
    if ((ret = nlist(KERNEL_LOC, nl)) == -1) {
Packit fcad23
        if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
				   NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
Packit fcad23
            return;
Packit fcad23
	} else {
Packit fcad23
            snmp_log_perror("nlist");
Packit fcad23
            exit(1);
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
#endif                          /*aix4 */
Packit fcad23
#endif                          /* ! HAVE_KVM_OPENFILES */
Packit fcad23
    for (ret = 0; nl[ret].n_name != NULL; ret++) {
Packit fcad23
#if defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
Packit fcad23
        if (nl[ret].n_type == 0 && nl[ret].n_value != 0)
Packit fcad23
            nl[ret].n_type = 1;
Packit fcad23
#endif
Packit fcad23
        if (nl[ret].n_type == 0) {
Packit fcad23
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
Packit fcad23
                DEBUGMSGTL(("auto_nlist:init_nlist", "nlist err:  %s not found\n",
Packit fcad23
                            nl[ret].n_name));
Packit fcad23
	    }
Packit fcad23
        } else {
Packit fcad23
            DEBUGMSGTL(("auto_nlist:init_nlist", "nlist: %s 0x%X\n", nl[ret].n_name,
Packit fcad23
                        (unsigned int) nl[ret].n_value));
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
}
Packit fcad23
Packit fcad23
int
Packit fcad23
KNLookup(struct nlist nl[], int nl_which, char *buf, size_t s)
Packit fcad23
{
Packit fcad23
    struct nlist   *nlp = &nl[nl_which];
Packit fcad23
Packit fcad23
    if (nlp->n_value == 0) {
Packit fcad23
        snmp_log(LOG_ERR, "Accessing non-nlisted variable: %s\n",
Packit fcad23
                 nlp->n_name);
Packit fcad23
        nlp->n_value = -1;      /* only one error message ... */
Packit fcad23
        return 0;
Packit fcad23
    }
Packit fcad23
    if (nlp->n_value == -1)
Packit fcad23
        return 0;
Packit fcad23
Packit fcad23
    return klookup(nlp->n_value, buf, s);
Packit fcad23
}
Packit fcad23
Packit fcad23
#ifdef TESTING
Packit fcad23
void
Packit fcad23
auto_nlist_print_tree(int indent, struct autonlist *ptr)
Packit fcad23
{
Packit fcad23
    char            buf[1024];
Packit fcad23
    if (indent == -2) {
Packit fcad23
        snmp_log(LOG_ERR, "nlist tree:\n");
Packit fcad23
        auto_nlist_print_tree(12, nlists);
Packit fcad23
    } else {
Packit fcad23
        if (ptr == 0)
Packit fcad23
            return;
Packit fcad23
        sprintf(buf, "%%%ds\n", indent);
Packit fcad23
        /*
Packit fcad23
         * DEBUGMSGTL(("auto_nlist", "buf: %s\n",buf)); 
Packit fcad23
         */
Packit fcad23
        DEBUGMSGTL(("auto_nlist", buf, ptr->symbol));
Packit fcad23
        auto_nlist_print_tree(indent + 2, ptr->left);
Packit fcad23
        auto_nlist_print_tree(indent + 2, ptr->right);
Packit fcad23
    }
Packit fcad23
}
Packit fcad23
#endif
Packit fcad23
#else                           /* !NETSNMP_CAN_USE_NLIST */
Packit fcad23
#include <net-snmp/agent/auto_nlist.h>
Packit fcad23
int
Packit fcad23
auto_nlist_noop(void)
Packit fcad23
{
Packit fcad23
    return 0;
Packit fcad23
}
Packit fcad23
#endif                          /* NETSNMP_CAN_USE_NLIST */