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;
 

Reply via email to