-/* $OpenBSD: application_internal.c,v 1.7 2023/11/08 19:46:28 martijn Exp $ */
+/* $OpenBSD: application_internal.c,v 1.8 2023/11/12 16:03:41 martijn Exp $ */
/*
* Copyright (c) 2023 Martijn van Duren <martijn@openbsd.org>
#include <sys/tree.h>
+#include <errno.h>
#include <event.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include "application.h"
/* 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;
};
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 *);
.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 = 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_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) {
+ if (obj->stringval != NULL)
+ free(obj->stringval);
+ free(obj);
+ } else
+ RB_INSERT(appl_internal_objects, &appl_internal_objects,
+ obj);
+ }
}
void
RB_INSERT(appl_internal_objects, &appl_internal_objects, obj);
}
+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)
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)
{
-/* $OpenBSD: parse.y,v 1.80 2023/11/04 09:38:47 martijn Exp $ */
+/* $OpenBSD: parse.y,v 1.81 2023/11/12 16:03:41 martijn Exp $ */
/*
* Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
#include <string.h>
#include <syslog.h>
+#include "application.h"
#include "snmpd.h"
#include "mib.h"
struct snmpd *conf = NULL;
static int errors = 0;
static struct usmuser *user = NULL;
+static struct oid *smi_object;
static uint8_t engineid[SNMPD_MAXENGINEIDLEN];
static int32_t enginepen;
%type <v.number> listenproto listenflag listenflags
%type <v.string> srcaddr port
%type <v.number> optwrite yesno seclevel
-%type <v.data> objtype cmd hostauth hostauthv3 usmauthopts usmauthopt
+%type <v.data> cmd hostauth hostauthv3 usmauthopts usmauthopt
%type <v.oid> oid hostoid trapoid
%type <v.auth> auth
%type <v.enc> enc
| grammar varset '\n'
| grammar main '\n'
| grammar system '\n'
- | grammar mib '\n'
+ | grammar object '\n'
| grammar error '\n' { file->errors++; }
;
}
;
-mib : OBJECTID oid NAME STRING optwrite objtype {
- struct oid *oid;
- if ((oid = (struct oid *)
- calloc(1, sizeof(*oid))) == NULL) {
+object : OBJECTID oid NAME STRING optwrite {
+ smi_object = calloc(1, sizeof(*smi_object));
+ if (smi_object == NULL) {
yyerror("calloc");
free($2);
- free($6.data);
+ free($4);
YYERROR;
}
- smi_oidlen($2);
- bcopy($2, &oid->o_id, sizeof(struct ber_oid));
- free($2);
- oid->o_name = $4;
- oid->o_data = $6.data;
- oid->o_val = $6.value;
- switch ($6.type) {
- case 1:
- oid->o_get = mps_getint;
- break;
- case 2:
- oid->o_get = mps_getstr;
- break;
- }
- oid->o_flags = OID_RD|OID_DYNAMIC;
+ smi_object->o_id = *$2;
+ smi_object->o_name = $4;
- if (smi_insert(oid) == -1) {
+ if (smi_insert(smi_object) == -1) {
yyerror("duplicate oid");
- free(oid->o_name);
- free(oid->o_data);
+ free($2);
+ free($4);
+ free(smi_object);
YYERROR;
}
- }
+ } objectvalue
;
-objtype : INTEGER NUMBER {
- $$.type = 1;
- $$.data = NULL;
- $$.value = $2;
+objectvalue : INTEGER NUMBER {
+ const char *error;
+
+ if ($2 < INT32_MIN) {
+ yyerror("number too small");
+ YYERROR;
+ }
+ if ($2 > INT32_MAX) {
+ yyerror("number too large");
+ YYERROR;
+ }
+ error = appl_internal_object_int(&smi_object->o_id, $2);
+ if (error != NULL) {
+ yyerror("%s", error);
+ YYERROR;
+ }
}
| OCTETSTRING STRING {
- $$.type = 2;
- $$.data = $2;
- $$.value = strlen($2);
+ const char *error;
+
+ if ((error = appl_internal_object_string(
+ &smi_object->o_id, $2)) != NULL) {
+ yyerror("%s", error);
+ free($2);
+ YYERROR;
+ }
+
}
;