File: [local] / src / usr.sbin / snmpd / application_internal.c (download)
Revision 1.12, Tue Feb 6 12:44:27 2024 UTC (3 months, 3 weeks ago) by martijn
Branch: MAIN
CVS Tags: OPENBSD_7_5_BASE, OPENBSD_7_5, HEAD Changes since 1.11: +6 -6 lines
Replace most smi_oid2string() calls with the new mib_oid2string().
smi_oid2string() is still called from trap handle context to not break
any existing scripts.
OK tb@
|
/* $OpenBSD: application_internal.c,v 1.12 2024/02/06 12:44:27 martijn Exp $ */
/*
* Copyright (c) 2023 Martijn van Duren <martijn@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/tree.h>
#include <sys/types.h>
#include <stddef.h>
#include <ber.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "application.h"
#include "log.h"
#include "mib.h"
#include "smi.h"
#include "snmp.h"
#include "snmpd.h"
struct appl_internal_object {
struct ber_oid oid;
struct ber_element * (*get)(struct ber_oid *);
/* No getnext means the object is scalar */
struct ber_element * (*getnext)(int8_t, struct ber_oid *);
int32_t intval;
char *stringval;
RB_ENTRY(appl_internal_object) entry;
};
void appl_internal_region(struct ber_oid *);
void appl_internal_object(struct ber_oid *,
struct ber_element *(*)(struct ber_oid *),
struct ber_element *(*)(int8_t, struct ber_oid *));
void appl_internal_get(struct appl_backend *, int32_t, int32_t, const char *,
struct appl_varbind *);
void appl_internal_getnext(struct appl_backend *, int32_t, int32_t,
const char *, struct appl_varbind *);
struct ber_element *appl_internal_snmp(struct ber_oid *);
struct ber_element *appl_internal_engine(struct ber_oid *);
struct ber_element *appl_internal_usmstats(struct ber_oid *);
struct ber_element *appl_internal_system(struct ber_oid *);
struct ber_element *appl_internal_get_int(struct ber_oid *);
struct ber_element *appl_internal_get_string(struct ber_oid *);
struct appl_internal_object *appl_internal_object_parent(struct ber_oid *);
int appl_internal_object_cmp(struct appl_internal_object *,
struct appl_internal_object *);
struct appl_backend_functions appl_internal_functions = {
.ab_get = appl_internal_get,
.ab_getnext = appl_internal_getnext,
.ab_getbulk = NULL, /* getbulk is too complex */
};
struct appl_backend appl_internal = {
.ab_name = "internal",
.ab_cookie = NULL,
.ab_retries = 0,
.ab_range = 1,
.ab_fn = &appl_internal_functions
};
struct appl_backend appl_config = {
.ab_name = "config",
.ab_cookie = NULL,
.ab_retries = 0,
.ab_range = 1,
.ab_fn = &appl_internal_functions
};
static RB_HEAD(appl_internal_objects, appl_internal_object)
appl_internal_objects = RB_INITIALIZER(&appl_internal_objects),
appl_internal_objects_conf = RB_INITIALIZER(&appl_internal_objects_conf);
RB_PROTOTYPE_STATIC(appl_internal_objects, appl_internal_object, entry,
appl_internal_object_cmp);
void
appl_internal_init(void)
{
struct appl_internal_object *obj;
struct ber_oid oid;
appl_internal_region(&OID(MIB_system));
appl_internal_object(&OID(MIB_sysDescr), appl_internal_system, NULL);
appl_internal_object(&OID(MIB_sysOID), appl_internal_system, NULL);
appl_internal_object(&OID(MIB_sysUpTime), appl_internal_system, NULL);
appl_internal_object(&OID(MIB_sysContact), appl_internal_system, NULL);
appl_internal_object(&OID(MIB_sysName), appl_internal_system, NULL);
appl_internal_object(&OID(MIB_sysLocation), appl_internal_system, NULL);
appl_internal_object(&OID(MIB_sysServices), appl_internal_system, NULL);
appl_internal_object(&OID(MIB_sysORLastChange), appl_sysorlastchange,
NULL);
appl_internal_object(&OID(MIB_sysORID), appl_sysortable,
appl_sysortable_getnext);
appl_internal_object(&OID(MIB_sysORDescr), appl_sysortable,
appl_sysortable_getnext);
appl_internal_object(&OID(MIB_sysORUpTime), appl_sysortable,
appl_sysortable_getnext);
appl_internal_region(&OID(MIB_snmp));
appl_internal_object(&OID(MIB_snmpInPkts), appl_internal_snmp, NULL);
appl_internal_object(&OID(MIB_snmpOutPkts), appl_internal_snmp, NULL);
appl_internal_object(&OID(MIB_snmpInBadVersions), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpInBadCommunityNames),
appl_internal_snmp, NULL);
appl_internal_object(&OID(MIB_snmpInBadCommunityUses),
appl_internal_snmp, NULL);
appl_internal_object(&OID(MIB_snmpInASNParseErrs), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpInTooBigs), appl_internal_snmp, NULL);
appl_internal_object(&OID(MIB_snmpInNoSuchNames), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpInBadValues), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpInReadOnlys), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpInGenErrs), appl_internal_snmp, NULL);
appl_internal_object(&OID(MIB_snmpInTotalReqVars), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpInTotalSetVars), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpInGetRequests), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpInGetNexts), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpInSetRequests), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpInGetResponses), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpInTraps), appl_internal_snmp, NULL);
appl_internal_object(&OID(MIB_snmpOutTooBigs), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpOutNoSuchNames), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpOutBadValues), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpOutGenErrs), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpOutGetRequests), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpOutGetNexts), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpOutSetRequests), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpOutGetResponses), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpOutTraps), appl_internal_snmp, NULL);
appl_internal_object(&OID(MIB_snmpEnableAuthenTraps),
appl_internal_snmp, NULL);
appl_internal_object(&OID(MIB_snmpSilentDrops), appl_internal_snmp,
NULL);
appl_internal_object(&OID(MIB_snmpProxyDrops), appl_internal_snmp,
NULL);
appl_internal_region(&OID(MIB_snmpV2));
appl_internal_object(&OID(MIB_snmpEngineID), appl_internal_engine,
NULL);
appl_internal_object(&OID(MIB_snmpEngineBoots), appl_internal_engine,
NULL);
appl_internal_object(&OID(MIB_snmpEngineTime), appl_internal_engine,
NULL);
appl_internal_object(&OID(MIB_snmpEngineMaxMsgSize),
appl_internal_engine, NULL);
appl_internal_object(&OID(MIB_snmpUnavailableContexts),
appl_targetmib, NULL);
appl_internal_object(&OID(MIB_snmpUnknownContexts),
appl_targetmib, NULL);
appl_internal_object(&OID(MIB_usmStatsUnsupportedSecLevels),
appl_internal_usmstats, NULL);
appl_internal_object(&OID(MIB_usmStatsNotInTimeWindow),
appl_internal_usmstats, NULL);
appl_internal_object(&OID(MIB_usmStatsUnknownUserNames),
appl_internal_usmstats, NULL);
appl_internal_object(&OID(MIB_usmStatsUnknownEngineId),
appl_internal_usmstats, NULL);
appl_internal_object(&OID(MIB_usmStatsWrongDigests),
appl_internal_usmstats, NULL);
appl_internal_object(&OID(MIB_usmStatsDecryptionErrors),
appl_internal_usmstats, NULL);
while ((obj = RB_MIN(appl_internal_objects,
&appl_internal_objects_conf)) != NULL) {
RB_REMOVE(appl_internal_objects,
&appl_internal_objects_conf, obj);
oid = obj->oid;
oid.bo_id[oid.bo_n++] = 0;
if (appl_register(NULL, 150, 1, &oid,
1, 1, 0, 0, &appl_config) != APPL_ERROR_NOERROR) {
free(obj->stringval);
free(obj);
} else
RB_INSERT(appl_internal_objects, &appl_internal_objects,
obj);
}
}
void
appl_internal_shutdown(void)
{
struct appl_internal_object *object;
while ((object = RB_ROOT(&appl_internal_objects)) != NULL) {
RB_REMOVE(appl_internal_objects, &appl_internal_objects,
object);
free(object->stringval);
free(object);
}
appl_close(&appl_internal);
appl_close(&appl_config);
}
void
appl_internal_region(struct ber_oid *oid)
{
enum appl_error error;
char oidbuf[1024];
error = appl_register(NULL, 150, 1, oid, 0, 1, 0, 0, &appl_internal);
/*
* Ignore requestDenied, duplicateRegistration, and unsupportedContext
*/
if (error == APPL_ERROR_PROCESSINGERROR ||
error == APPL_ERROR_PARSEERROR)
fatalx("internal: Failed to register %s", mib_oid2string(oid,
oidbuf, sizeof(oidbuf), snmpd_env->sc_oidfmt));
}
void
appl_internal_object(struct ber_oid *oid,
struct ber_element *(*get)(struct ber_oid *),
struct ber_element *(*getnext)(int8_t, struct ber_oid *))
{
struct appl_internal_object *obj;
char buf[1024];
if ((obj = calloc(1, sizeof(*obj))) == NULL)
fatal(NULL);
obj->oid = *oid;
obj->get = get;
obj->getnext = getnext;
obj->stringval = NULL;
if (RB_INSERT(appl_internal_objects,
&appl_internal_objects, obj) != NULL)
fatalx("%s: %s already registered", __func__,
mib_oid2string(oid, buf, sizeof(buf),
snmpd_env->sc_oidfmt));
}
const char *
appl_internal_object_int(struct ber_oid *oid, int32_t val)
{
struct appl_internal_object *obj;
if ((obj = calloc(1, sizeof(*obj))) == NULL)
return strerror(errno);
obj->oid = *oid;
obj->get = appl_internal_get_int;
obj->getnext = NULL;
obj->intval = val;
obj->stringval = NULL;
if (RB_INSERT(appl_internal_objects,
&appl_internal_objects_conf, obj) != NULL) {
free(obj);
return "OID already defined";
}
return NULL;
}
const char *
appl_internal_object_string(struct ber_oid *oid, char *val)
{
struct appl_internal_object *obj;
if ((obj = calloc(1, sizeof(*obj))) == NULL)
return strerror(errno);
obj->oid = *oid;
obj->get = appl_internal_get_string;
obj->getnext = NULL;
obj->stringval = val;
if (RB_INSERT(appl_internal_objects,
&appl_internal_objects_conf, obj) != NULL) {
free(obj);
return "OID already defined";
}
return NULL;
}
void
appl_internal_get(struct appl_backend *backend, __unused int32_t transactionid,
int32_t requestid, __unused const char *ctx, struct appl_varbind *vblist)
{
struct ber_oid oid;
struct appl_internal_object *object;
struct appl_varbind *vb, *resp;
size_t i;
int r;
for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next, i++)
continue;
if ((resp = calloc(i, sizeof(*resp))) == NULL) {
log_warn("%s", backend->ab_name);
appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vblist);
return;
}
for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next, i++) {
resp[i].av_oid = vb->av_oid;
if ((object = appl_internal_object_parent(&vb->av_oid)) == NULL)
resp[i].av_value =
appl_exception(APPL_EXC_NOSUCHOBJECT);
else {
oid = object->oid;
/* Add 0 element for scalar */
if (object->getnext == NULL)
oid.bo_id[oid.bo_n++] = 0;
r = ober_oid_cmp(&vb->av_oid, &oid);
if ((r == 0 && object->getnext == NULL) ||
(r == 2 && object->getnext != NULL))
resp[i].av_value = object->get(&resp[i].av_oid);
else
resp[i].av_value =
appl_exception(APPL_EXC_NOSUCHINSTANCE);
}
if (resp[i].av_value == NULL) {
log_warnx("%s: Failed to get value", backend->ab_name);
goto fail;
}
resp[i].av_next = &resp[i + 1];
}
resp[i - 1].av_next = NULL;
appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, resp);
free(resp);
return;
fail:
for (vb = resp; vb != NULL; vb = vb->av_next)
ober_free_elements(vb->av_value);
free(resp);
appl_response(backend, requestid, APPL_ERROR_GENERR, i + 1, vblist);
}
void
appl_internal_getnext(struct appl_backend *backend,
__unused int32_t transactionid, int32_t requestid, __unused const char *ctx,
struct appl_varbind *vblist)
{
struct ber_oid oid;
struct appl_internal_object *object, search;
struct appl_varbind *vb, *resp;
size_t i;
int r;
int8_t include;
for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next, i++)
continue;
if ((resp = calloc(i, sizeof(*resp))) == NULL) {
log_warn("%s", backend->ab_name);
appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vblist);
return;
}
for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next, i++) {
resp[i].av_oid = vb->av_oid;
object = appl_internal_object_parent(&vb->av_oid);
if (object == NULL) {
search.oid = vb->av_oid;
object = RB_NFIND(appl_internal_objects,
&appl_internal_objects, &search);
}
include = vb->av_include;
for (; object != NULL; object = RB_NEXT(appl_internal_objects,
&appl_internal_objects, object), include = 1) {
if (object->getnext == NULL) {
oid = object->oid;
oid.bo_id[oid.bo_n++] = 0;
r = ober_oid_cmp(&resp[i].av_oid, &oid);
if (r > 0 || (r == 0 && !include))
continue;
resp[i].av_oid = oid;
resp[i].av_value = object->get(&oid);
break;
}
/* non-scalar */
if (ober_oid_cmp(&object->oid, &resp[i].av_oid) > 0) {
include = 1;
resp[i].av_oid = object->oid;
}
resp[i].av_value =
object->getnext(include, &resp[i].av_oid);
if (resp[i].av_value == NULL ||
resp[i].av_value->be_class != BER_CLASS_CONTEXT)
break;
/* endOfMibView */
ober_free_elements(resp[i].av_value);
resp[i].av_value = NULL;
}
if (ober_oid_cmp(&resp[i].av_oid, &vb->av_oid_end) >= 0 ||
object == NULL) {
resp[i].av_oid = vb->av_oid;
ober_free_elements(resp[i].av_value);
resp[i].av_value =
appl_exception(APPL_EXC_ENDOFMIBVIEW);
}
if (resp[i].av_value == NULL) {
log_warnx("%s: Failed to get value", backend->ab_name);
goto fail;
}
resp[i].av_next = &resp[i + 1];
}
resp[i - 1].av_next = NULL;
appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, resp);
free(resp);
return;
fail:
for (vb = resp; vb != NULL; vb = vb->av_next)
ober_free_elements(vb->av_value);
free(resp);
appl_response(backend, requestid, APPL_ERROR_GENERR, i + 1, vblist);
}
struct ber_element *
appl_internal_snmp(struct ber_oid *oid)
{
struct snmp_stats *stats = &snmpd_env->sc_stats;
struct ber_element *value = NULL;
if (ober_oid_cmp(oid, &OID(MIB_snmpEnableAuthenTraps, 0)) == 0)
return ober_add_integer(NULL,
stats->snmp_enableauthentraps ? 1 : 2);
if (ober_oid_cmp(&OID(MIB_snmpInPkts, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_inpkts);
else if (ober_oid_cmp(&OID(MIB_snmpOutPkts, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_outpkts);
else if (ober_oid_cmp(&OID(MIB_snmpInBadVersions, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_inbadversions);
else if (ober_oid_cmp(&OID(MIB_snmpInBadCommunityNames, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_inbadcommunitynames);
else if (ober_oid_cmp(&OID(MIB_snmpInBadCommunityUses, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_inbadcommunityuses);
else if (ober_oid_cmp(&OID(MIB_snmpInASNParseErrs, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_inasnparseerrs);
else if (ober_oid_cmp(&OID(MIB_snmpInTooBigs, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_intoobigs);
else if (ober_oid_cmp(&OID(MIB_snmpInNoSuchNames, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_innosuchnames);
else if (ober_oid_cmp(&OID(MIB_snmpInBadValues, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_inbadvalues);
else if (ober_oid_cmp(&OID(MIB_snmpInReadOnlys, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_inreadonlys);
else if (ober_oid_cmp(&OID(MIB_snmpInGenErrs, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_ingenerrs);
else if (ober_oid_cmp(&OID(MIB_snmpInTotalReqVars, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_intotalreqvars);
else if (ober_oid_cmp(&OID(MIB_snmpInTotalSetVars, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_intotalsetvars);
else if (ober_oid_cmp(&OID(MIB_snmpInGetRequests, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_ingetrequests);
else if (ober_oid_cmp(&OID(MIB_snmpInGetNexts, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_ingetnexts);
else if (ober_oid_cmp(&OID(MIB_snmpInSetRequests, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_insetrequests);
else if (ober_oid_cmp(&OID(MIB_snmpInGetResponses, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_ingetresponses);
else if (ober_oid_cmp(&OID(MIB_snmpInTraps, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_intraps);
else if (ober_oid_cmp(&OID(MIB_snmpOutTooBigs, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_outtoobigs);
else if (ober_oid_cmp(&OID(MIB_snmpOutNoSuchNames, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_outnosuchnames);
else if (ober_oid_cmp(&OID(MIB_snmpOutBadValues, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_outbadvalues);
else if (ober_oid_cmp(&OID(MIB_snmpOutGenErrs, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_outgenerrs);
else if (ober_oid_cmp(&OID(MIB_snmpOutGetRequests, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_outgetrequests);
else if (ober_oid_cmp(&OID(MIB_snmpOutGetNexts, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_outgetnexts);
else if (ober_oid_cmp(&OID(MIB_snmpOutSetRequests, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_outsetrequests);
else if (ober_oid_cmp(&OID(MIB_snmpOutGetResponses, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_outgetresponses);
else if (ober_oid_cmp(&OID(MIB_snmpOutTraps, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_outtraps);
else if (ober_oid_cmp(&OID(MIB_snmpSilentDrops, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_silentdrops);
else if (ober_oid_cmp(&OID(MIB_snmpProxyDrops, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_proxydrops);
if (value != NULL)
ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
return value;
}
struct ber_element *
appl_internal_engine(struct ber_oid *oid)
{
if (ober_oid_cmp(&OID(MIB_snmpEngineID, 0), oid) == 0)
return ober_add_nstring(NULL, snmpd_env->sc_engineid,
snmpd_env->sc_engineid_len);
else if (ober_oid_cmp(&OID(MIB_snmpEngineBoots, 0), oid) == 0)
return ober_add_integer(NULL, snmpd_env->sc_engine_boots);
else if (ober_oid_cmp(&OID(MIB_snmpEngineTime, 0), oid) == 0)
return ober_add_integer(NULL, snmpd_engine_time());
else if (ober_oid_cmp(&OID(MIB_snmpEngineMaxMsgSize, 0), oid) == 0)
return ober_add_integer(NULL, READ_BUF_SIZE);
return NULL;
}
struct ber_element *
appl_internal_usmstats(struct ber_oid *oid)
{
struct snmp_stats *stats = &snmpd_env->sc_stats;
struct ber_element *value = NULL;
if (ober_oid_cmp(&OID(MIB_usmStatsUnsupportedSecLevels, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_usmbadseclevel);
else if (ober_oid_cmp(&OID(MIB_usmStatsNotInTimeWindow, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_usmtimewindow);
else if (ober_oid_cmp(&OID(MIB_usmStatsUnknownUserNames, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_usmnosuchuser);
else if (ober_oid_cmp(&OID(MIB_usmStatsUnknownEngineId, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_usmnosuchengine);
else if (ober_oid_cmp(&OID(MIB_usmStatsWrongDigests, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_usmwrongdigest);
else if (ober_oid_cmp(&OID(MIB_usmStatsDecryptionErrors, 0), oid) == 0)
value = ober_add_integer(NULL, stats->snmp_usmdecrypterr);
if (value != NULL)
ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
return value;
}
struct ber_element *
appl_internal_system(struct ber_oid *oid)
{
struct snmp_system *s = &snmpd_env->sc_system;
struct ber_element *value = NULL;
if (ober_oid_cmp(&OID(MIB_sysDescr, 0), oid) == 0)
return ober_add_string(NULL, s->sys_descr);
else if (ober_oid_cmp(&OID(MIB_sysOID, 0), oid) == 0)
return ober_add_oid(NULL, &s->sys_oid);
else if (ober_oid_cmp(&OID(MIB_sysUpTime, 0), oid) == 0) {
value = ober_add_integer(NULL, smi_getticks());
ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
} else if (ober_oid_cmp(&OID(MIB_sysContact, 0), oid) == 0)
return ober_add_string(NULL, s->sys_contact);
else if (ober_oid_cmp(&OID(MIB_sysName, 0), oid) == 0)
return ober_add_string(NULL, s->sys_name);
else if (ober_oid_cmp(&OID(MIB_sysLocation, 0), oid) == 0)
return ober_add_string(NULL, s->sys_location);
else if (ober_oid_cmp(&OID(MIB_sysServices, 0), oid) == 0)
return ober_add_integer(NULL, s->sys_services);
return value;
}
struct ber_element *
appl_internal_get_int(struct ber_oid *oid)
{
struct appl_internal_object *obj;
obj = appl_internal_object_parent(oid);
return ober_add_integer(NULL, obj->intval);
}
struct ber_element *
appl_internal_get_string(struct ber_oid *oid)
{
struct appl_internal_object *obj;
obj = appl_internal_object_parent(oid);
return ober_add_string(NULL, obj->stringval);
}
struct appl_internal_object *
appl_internal_object_parent(struct ber_oid *oid)
{
struct appl_internal_object *object, search;
search.oid = *oid;
do {
if ((object = RB_FIND(appl_internal_objects,
&appl_internal_objects, &search)) != NULL)
return object;
} while (--search.oid.bo_n > 0);
return NULL;
}
int
appl_internal_object_cmp(struct appl_internal_object *o1,
struct appl_internal_object *o2)
{
return ober_oid_cmp(&o1->oid, &o2->oid);
}
RB_GENERATE_STATIC(appl_internal_objects, appl_internal_object, entry,
appl_internal_object_cmp);