-# $OpenBSD: Makefile,v 1.23 2023/11/04 09:22:52 martijn Exp $
+# $OpenBSD: Makefile,v 1.24 2023/11/04 09:38:47 martijn Exp $
PROG= snmpd
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
-/* $OpenBSD: application_internal.c,v 1.3 2023/11/04 09:30:28 martijn Exp $ */
+/* $OpenBSD: application_internal.c,v 1.4 2023/11/04 09:38:47 martijn Exp $ */
/*
* Copyright (c) 2023 Martijn van Duren <martijn@openbsd.org>
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 *);
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);
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)
{
+++ /dev/null
-/* $OpenBSD: mib.c,v 1.107 2023/11/04 09:30:28 martijn Exp $ */
-
-/*
- * Copyright (c) 2012 Joel Knight <joel@openbsd.org>
- * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@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/types.h>
-#include <sys/signal.h>
-#include <sys/queue.h>
-#include <sys/proc.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/time.h>
-#include <sys/tree.h>
-#include <sys/utsname.h>
-#include <sys/sysctl.h>
-#include <sys/sensors.h>
-#include <sys/sched.h>
-#include <sys/mount.h>
-#include <sys/ioctl.h>
-#include <sys/disk.h>
-
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip_carp.h>
-#include <netinet/ip_var.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <net/if_types.h>
-#include <net/pfvar.h>
-#include <netinet/ip_ipsp.h>
-#include <net/if_pfsync.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <event.h>
-#include <fcntl.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <pwd.h>
-#include <limits.h>
-#include <kvm.h>
-
-#include "snmpd.h"
-#include "mib.h"
-
-/*
- * Defined in SNMPv2-MIB.txt (RFC 3418)
- */
-
-int mib_getsys(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_sysor(struct oid *, struct ber_oid *, struct ber_element **);
-
-static struct oid mib_tree[] = MIB_TREE;
-
-/* base MIB tree */
-static struct oid base_mib[] = {
- { MIB(mib_2), OID_MIB },
- { MIB(sysDescr), OID_RD, mib_getsys },
- { MIB(sysOID), OID_RD, mib_getsys },
- { MIB(sysUpTime), OID_RD, mib_getsys },
- { MIB(sysContact), OID_RD, mib_getsys },
- { MIB(sysName), OID_RD, mib_getsys },
- { MIB(sysLocation), OID_RD, mib_getsys },
- { MIB(sysServices), OID_RS, mib_getsys },
- { MIB(sysORLastChange), OID_RD, mps_getts },
- { MIB(sysORIndex), OID_TRD, mib_sysor },
- { MIB(sysORID), OID_TRD, mib_sysor },
- { MIB(sysORDescr), OID_TRD, mib_sysor },
- { MIB(sysORUpTime), OID_TRD, mib_sysor },
- { MIBEND }
-};
-
-int
-mib_getsys(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_oid sysoid = OID(MIB_SYSOID_DEFAULT);
- char *s = oid->o_data;
- struct ber_oid *so = oid->o_data;
- struct utsname u;
- long long ticks;
-
- if (uname(&u) == -1)
- return (-1);
-
- switch (oid->o_oid[OIDIDX_system]) {
- case 1:
- if (s == NULL) {
- if (asprintf(&s, "%s %s %s %s %s",
- u.sysname, u.nodename, u.release,
- u.version, u.machine) == -1)
- return (-1);
- oid->o_data = s;
- oid->o_val = strlen(s);
- }
- *elm = ober_add_string(*elm, s);
- break;
- case 2:
- if (so == NULL)
- so = &sysoid;
- smi_oidlen(so);
- *elm = ober_add_oid(*elm, so);
- break;
- case 3:
- ticks = smi_getticks();
- *elm = ober_add_integer(*elm, ticks);
- ober_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
- break;
- case 4:
- if (s == NULL) {
- if (asprintf(&s, "root@%s", u.nodename) == -1)
- return (-1);
- oid->o_data = s;
- oid->o_val = strlen(s);
- }
- *elm = ober_add_string(*elm, s);
- break;
- case 5:
- if (s == NULL) {
- if ((s = strdup(u.nodename)) == NULL)
- return (-1);
- oid->o_data = s;
- oid->o_val = strlen(s);
- }
- *elm = ober_add_string(*elm, s);
- break;
- case 6:
- if (s == NULL)
- s = "";
- *elm = ober_add_string(*elm, s);
- break;
- case 7:
- *elm = ober_add_integer(*elm, oid->o_val);
- break;
- default:
- return (-1);
- }
- return (0);
-}
-
-int
-mib_sysor(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- u_int32_t idx = 1, nmib = 0;
- struct oid *next, *miboid;
- char buf[SNMPD_MAXSTRLEN];
-
- /* Count MIB root OIDs in the tree */
- for (next = NULL;
- (next = smi_foreach(next, OID_MIB)) != NULL; nmib++);
-
- /* Get and verify the current row index */
- idx = o->bo_id[OIDIDX_sysOREntry];
- if (idx > nmib)
- return (1);
-
- /* Find the MIB root element for this Id */
- for (next = miboid = NULL, nmib = 1;
- (next = smi_foreach(next, OID_MIB)) != NULL; nmib++) {
- if (nmib == idx)
- miboid = next;
- }
- if (miboid == NULL)
- return (-1);
-
- /* Tables need to prepend the OID on their own */
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_sysOR]) {
- case 1:
- ber = ober_add_integer(ber, idx);
- break;
- case 2:
- ber = ober_add_oid(ber, &miboid->o_id);
- break;
- case 3:
- /*
- * This should be a description of the MIB.
- * But we use the symbolic OID string for now, it may
- * help to display names of internal OIDs.
- */
- smi_oid2string(&miboid->o_id, buf, sizeof(buf), 0);
- ber = ober_add_string(ber, buf);
- break;
- case 4:
- /*
- * We do not support dynamic loading of MIB at runtime,
- * the sysORUpTime value of 0 will indicate "loaded at
- * startup".
- */
- ber = ober_add_integer(ber, 0);
- ober_set_header(ber,
- BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
- break;
- default:
- return (-1);
- }
-
- return (0);
-}
-
-/*
- * Import all MIBs
- */
-
-void
-mib_init(void)
-{
- /*
- * MIB declarations (to register the OID names)
- */
- smi_mibtree(mib_tree);
-
- /*
- * MIB definitions (the implementation)
- */
-
- /* SNMPv2-MIB */
- smi_mibtree(base_mib);
-}
-/* $OpenBSD: parse.y,v 1.79 2023/10/24 08:41:20 martijn Exp $ */
+/* $OpenBSD: parse.y,v 1.80 2023/11/04 09:38:47 martijn Exp $ */
/*
* Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
#include <sys/stat.h>
#include <sys/queue.h>
#include <sys/tree.h>
+#include <sys/utsname.h>
#include <netinet/in.h>
#include <net/if.h>
;
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;
}
;
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;
return (NULL);
}
+ conf->sc_system.sys_services = -1;
conf->sc_flags = flags;
conf->sc_confpath = filename;
TAILQ_INIT(&conf->sc_addresses);
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)
-/* $OpenBSD: smi.c,v 1.32 2022/10/06 14:41:08 martijn Exp $ */
+/* $OpenBSD: smi.c,v 1.33 2023/11/04 09:38:47 martijn Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org>
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);
{
/* Initialize the Structure of Managed Information (SMI) */
RB_INIT(&smi_oidtree);
- mib_init();
+ smi_mibtree(smi_objects);
return (0);
}
-/* $OpenBSD: snmpd.h,v 1.107 2023/11/04 09:22:52 martijn Exp $ */
+/* $OpenBSD: snmpd.h,v 1.108 2023/11/04 09:38:47 martijn Exp $ */
/*
* Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
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
size_t sc_engineid_len;
struct snmp_stats sc_stats;
+ struct snmp_system sc_system;
struct trap_addresslist sc_trapreceivers;