[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openbsd-tech
Subject:    snmpd: Move SNMPv2-MIB::system to application_internal.c
From:       Martijn van Duren <openbsd+tech () list ! imperialat ! at>
Date:       2023-10-29 19:12:14
Message-ID: 801592ca17d0ae6003e3659f3d3c8c8f32da636d.camel () list ! imperialat ! at
[Download RAW message or body]

This one is a little more involved than the previous 2. Since the
snmpd.conf's system variables are stored inside a 'struct oid', I want
to move these into their own struct inside 'struct snmpd'.

If we also move mib_tree to smi.c we can completely remove mib.c
As stated in my previous mail, this removes the sysORTable. I'll add
these back later in a proper way. (mib.c removal omitted from diff)

With these the only consumer of mps.c left is the oid keyword of
snmpd.conf.

OK?

martijn@

diff --git a/Makefile b/Makefile
index 3522a38..98bdda5 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ MAN=		snmpd.8 snmpd.conf.5
 SRCS=		parse.y log.c snmpe.c application.c application_legacy.c \
 		    application_blocklist.c application_internal.c \
 		    application_agentx.c ax.c \
-		    mps.c trap.c mib.c smi.c snmpd.c \
+		    mps.c trap.c smi.c snmpd.c \
 		    proc.c usm.c traphandler.c util.c
 
 LDADD=		-levent -lutil -lcrypto
diff --git a/application_internal.c b/application_internal.c
index 36ab8ef..e682cc7 100644
--- a/application_internal.c
+++ b/application_internal.c
@@ -47,6 +47,7 @@ void appl_internal_getnext(struct appl_backend *, int32_t, int32_t,
 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 appl_internal_object *appl_internal_object_parent(struct ber_oid *);
 int appl_internal_object_cmp(struct appl_internal_object *,
     struct appl_internal_object *);
@@ -73,6 +74,15 @@ RB_PROTOTYPE_STATIC(appl_internal_objects, appl_internal_object, entry,
 void
 appl_internal_init(void)
 {
+	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_region(&OID(MIB_snmp));
 	appl_internal_object(&OID(MIB_snmpInPkts), appl_internal_snmp, NULL);
 	appl_internal_object(&OID(MIB_snmpOutPkts), appl_internal_snmp, NULL);
@@ -441,6 +451,30 @@ appl_internal_usmstats(struct ber_oid *oid)
 	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 appl_internal_object *
 appl_internal_object_parent(struct ber_oid *oid)
 {
diff --git a/parse.y b/parse.y
index 8f9bad0..7ae7ce1 100644
--- a/parse.y
+++ b/parse.y
@@ -28,6 +28,7 @@
 #include <sys/stat.h>
 #include <sys/queue.h>
 #include <sys/tree.h>
+#include <sys/utsname.h>
 
 #include <netinet/in.h>
 #include <net/if.h>
@@ -760,28 +761,87 @@ system		: SYSTEM sysmib
 		;
 
 sysmib		: CONTACT STRING		{
-			struct ber_oid	 o = OID(MIB_sysContact);
-			mps_set(&o, $2, strlen($2));
+			if (conf->sc_system.sys_contact[0] != '\0') {
+				yyerror("system contact already defined");
+				free($2);
+				YYERROR;
+			}
+			if (strlcpy(conf->sc_system.sys_contact, $2,
+			    sizeof(conf->sc_system.sys_contact)) >=
+			    sizeof(conf->sc_system.sys_contact)) {
+				yyerror("system contact too long");
+				free($2);
+				YYERROR;
+			}
+			free($2);
 		}
 		| DESCR STRING			{
-			struct ber_oid	 o = OID(MIB_sysDescr);
-			mps_set(&o, $2, strlen($2));
+			if (conf->sc_system.sys_descr[0] != '\0') {
+				yyerror("system description already defined");
+				free($2);
+				YYERROR;
+			}
+			if (strlcpy(conf->sc_system.sys_descr, $2,
+			    sizeof(conf->sc_system.sys_descr)) >=
+			    sizeof(conf->sc_system.sys_descr)) {
+				yyerror("system description too long");
+				free($2);
+				YYERROR;
+			}
+			free($2);
 		}
 		| LOCATION STRING		{
-			struct ber_oid	 o = OID(MIB_sysLocation);
-			mps_set(&o, $2, strlen($2));
+			if (conf->sc_system.sys_location[0] != '\0') {
+				yyerror("system location already defined");
+				free($2);
+				YYERROR;
+			}
+			if (strlcpy(conf->sc_system.sys_location, $2,
+			    sizeof(conf->sc_system.sys_location)) >=
+			    sizeof(conf->sc_system.sys_location)) {
+				yyerror("system location too long");
+				free($2);
+				YYERROR;
+			}
+			free($2);
 		}
 		| NAME STRING			{
-			struct ber_oid	 o = OID(MIB_sysName);
-			mps_set(&o, $2, strlen($2));
+			if (conf->sc_system.sys_name[0] != '\0') {
+				yyerror("system name already defined");
+				free($2);
+				YYERROR;
+			}
+			if (strlcpy(conf->sc_system.sys_name, $2,
+			    sizeof(conf->sc_system.sys_name)) >=
+			    sizeof(conf->sc_system.sys_name)) {
+				yyerror("system name too long");
+				free($2);
+				YYERROR;
+			}
+			free($2);
 		}
 		| OBJECTID oid			{
-			struct ber_oid	 o = OID(MIB_sysOID);
-			mps_set(&o, $2, sizeof(struct ber_oid));
+			if (conf->sc_system.sys_oid.bo_n != 0) {
+				yyerror("system oid already defined");
+				free($2);
+				YYERROR;
+			}
+			conf->sc_system.sys_oid = *$2;
+			free($2);
 		}
 		| SERVICES NUMBER		{
-			struct ber_oid	 o = OID(MIB_sysServices);
-			mps_set(&o, NULL, $2);
+			if (conf->sc_system.sys_services != -1) {
+				yyerror("system services already defined");
+				YYERROR;
+			}
+			if ($2 < 0) {
+				yyerror("system services too small");
+				YYERROR;
+			} else if ($2 > 127) {
+				yyerror("system services too large");
+				YYERROR;
+			}
+			conf->sc_system.sys_services = $2;
 		}
 		;
 
@@ -1575,6 +1635,7 @@ struct snmpd *
 parse_config(const char *filename, u_int flags)
 {
 	struct sockaddr_storage ss;
+	struct utsname u;
 	struct sym	*sym, *next;
 	struct address	*h;
 	struct trap_address	*tr;
@@ -1589,6 +1650,7 @@ parse_config(const char *filename, u_int flags)
 		return (NULL);
 	}
 
+	conf->sc_system.sys_services = -1;
 	conf->sc_flags = flags;
 	conf->sc_confpath = filename;
 	TAILQ_INIT(&conf->sc_addresses);
@@ -1609,6 +1671,25 @@ parse_config(const char *filename, u_int flags)
 
 	endservent();
 
+	if (uname(&u) == -1)
+		fatal("uname");
+
+	if (conf->sc_system.sys_descr[0] == '\0')
+		snprintf(conf->sc_system.sys_descr,
+		    sizeof(conf->sc_system.sys_descr), "%s %s %s %s %s",
+		    u.sysname, u.nodename, u.release, u.version, u.machine);
+	if (conf->sc_system.sys_oid.bo_n == 0)
+		conf->sc_system.sys_oid = OID(MIB_SYSOID_DEFAULT);
+	if (conf->sc_system.sys_contact[0] == '\0')
+		snprintf(conf->sc_system.sys_contact,
+		    sizeof(conf->sc_system.sys_contact), "root@%s", u.nodename);
+	if (conf->sc_system.sys_name[0] == '\0')
+		snprintf(conf->sc_system.sys_name,
+		    sizeof(conf->sc_system.sys_name), "%s", u.nodename);
+	if (conf->sc_system.sys_services == -1)
+		conf->sc_system.sys_services = 0;
+
+
 	/* Must be identical to enginefmt_local:HOSTHASH */
 	if (conf->sc_engineid_len == 0) {
 		if (gethostname(hostname, sizeof(hostname)) == -1)
diff --git a/smi.c b/smi.c
index 3a5b3ba..655904d 100644
--- a/smi.c
+++ b/smi.c
@@ -53,6 +53,7 @@
 RB_HEAD(oidtree, oid);
 RB_PROTOTYPE(oidtree, oid, o_element, smi_oid_cmp);
 struct oidtree smi_oidtree;
+static struct oid smi_objects[] = MIB_TREE;
 
 RB_HEAD(keytree, oid);
 RB_PROTOTYPE(keytree, oid, o_keyword, smi_key_cmp);
@@ -231,7 +232,7 @@ smi_init(void)
 {
 	/* Initialize the Structure of Managed Information (SMI) */
 	RB_INIT(&smi_oidtree);
-	mib_init();
+	smi_mibtree(smi_objects);
 	return (0);
 }
 
diff --git a/snmpd.h b/snmpd.h
index 8313a79..d0b6914 100644
--- a/snmpd.h
+++ b/snmpd.h
@@ -428,6 +428,15 @@ struct usmuser {
 	SLIST_ENTRY(usmuser)	 uu_next;
 };
 
+struct snmp_system {
+	char			 sys_descr[256];
+	struct ber_oid		 sys_oid;
+	char			 sys_contact[256];
+	char			 sys_name[256];
+	char			 sys_location[256];
+	int8_t			 sys_services;
+};
+
 struct snmpd {
 	u_int8_t		 sc_flags;
 #define SNMPD_F_VERBOSE		 0x01
@@ -448,6 +457,7 @@ struct snmpd {
 	size_t			 sc_engineid_len;
 
 	struct snmp_stats	 sc_stats;
+	struct snmp_system	 sc_system;
 
 	struct trap_addresslist	 sc_trapreceivers;
 

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic