|
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 */
|