From 2c7b58e5a87587a82925b3b313ea646e6542f11e Mon Sep 17 00:00:00 2001 From: martijn Date: Thu, 30 Jun 2022 09:42:19 +0000 Subject: [PATCH] Rewrite smi_print_element to be more concise and complete. Keep the old implementation around as smi_print_element_legacy for the trap handler scripts, so these don't break. Should help with request tracing. OK sthen@ --- usr.sbin/snmpd/smi.c | 140 ++++++++++++++++++++++++++++++++++- usr.sbin/snmpd/smi.h | 3 +- usr.sbin/snmpd/snmp.h | 8 +- usr.sbin/snmpd/traphandler.c | 4 +- 4 files changed, 149 insertions(+), 6 deletions(-) diff --git a/usr.sbin/snmpd/smi.c b/usr.sbin/snmpd/smi.c index 20471d8fd2e..f37443dfda4 100644 --- a/usr.sbin/snmpd/smi.c +++ b/usr.sbin/snmpd/smi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smi.c,v 1.30 2021/10/21 15:08:15 martijn Exp $ */ +/* $OpenBSD: smi.c,v 1.31 2022/06/30 09:42:19 martijn Exp $ */ /* * Copyright (c) 2007, 2008 Reyk Floeter @@ -46,6 +46,7 @@ #include "snmpd.h" #include "mib.h" +#include "application.h" #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) @@ -461,8 +462,9 @@ smi_debug_elements(struct ber_element *root) } #endif +/* Keep around so trap handle scripts don't break */ char * -smi_print_element(struct ber_element *root) +smi_print_element_legacy(struct ber_element *root) { char *str = NULL, *buf, *p; size_t len, i; @@ -530,6 +532,140 @@ smi_print_element(struct ber_element *root) return (NULL); } +char * +smi_print_element(struct ber_element *root) +{ + char *str = NULL, *buf, *p; + long long v; + struct ber_oid o; + char strbuf[BUFSIZ]; + + switch (root->be_class) { + case BER_CLASS_UNIVERSAL: + switch (root->be_type) { + case BER_TYPE_INTEGER: + if (ober_get_integer(root, &v) == -1) + goto fail; + if (asprintf(&str, "%lld", v) == -1) + goto fail; + break; + case BER_TYPE_OBJECT: + if (ober_get_oid(root, &o) == -1) + goto fail; + if (asprintf(&str, "%s", smi_oid2string(&o, strbuf, + sizeof(strbuf), 0)) == -1) + goto fail; + break; + case BER_TYPE_OCTETSTRING: + if (ober_get_string(root, &buf) == -1) + goto fail; + p = reallocarray(NULL, 4, root->be_len + 1); + if (p == NULL) + goto fail; + strvisx(p, buf, root->be_len, VIS_NL); + if (asprintf(&str, "\"%s\"", p) == -1) { + free(p); + goto fail; + } + free(p); + break; + case BER_TYPE_NULL: + if (asprintf(&str, "null") == -1) + goto fail; + break; + default: + /* Should not happen in a valid SNMP packet */ + if (asprintf(&str, "[U/%u]", root->be_type) == -1) + goto fail; + break; + } + break; + case BER_CLASS_APPLICATION: + switch (root->be_type) { + case SNMP_T_IPADDR: + if (ober_get_string(root, &buf) == -1) + goto fail; + if (asprintf(&str, "%s", + inet_ntoa(*(struct in_addr *)buf)) == -1) + goto fail; + break; + case SNMP_T_COUNTER32: + if (ober_get_integer(root, &v) == -1) + goto fail; + if (asprintf(&str, "%lld(c32)", v) == -1) + goto fail; + break; + case SNMP_T_GAUGE32: + if (ober_get_integer(root, &v) == -1) + goto fail; + if (asprintf(&str, "%lld(g32)", v) == -1) + goto fail; + break; + case SNMP_T_TIMETICKS: + if (ober_get_integer(root, &v) == -1) + goto fail; + if (asprintf(&str, "%lld.%llds", v/100, v%100) == -1) + goto fail; + break; + case SNMP_T_OPAQUE: + if (ober_get_string(root, &buf) == -1) + goto fail; + p = reallocarray(NULL, 4, root->be_len + 1); + if (p == NULL) + goto fail; + strvisx(p, buf, root->be_len, VIS_NL); + if (asprintf(&str, "\"%s\"(opaque)", p) == -1) { + free(p); + goto fail; + } + free(p); + break; + case SNMP_T_COUNTER64: + if (ober_get_integer(root, &v) == -1) + goto fail; + if (asprintf(&str, "%lld(c64)", v) == -1) + goto fail; + break; + default: + /* Should not happen in a valid SNMP packet */ + if (asprintf(&str, "[A/%u]", root->be_type) == -1) + goto fail; + break; + } + break; + case BER_CLASS_CONTEXT: + switch (root->be_type) { + case SNMP_V_NOSUCHOBJECT: + str = strdup("noSuchObject"); + break; + case SNMP_V_NOSUCHINSTANCE: + str = strdup("noSuchInstance"); + break; + case SNMP_V_ENDOFMIBVIEW: + str = strdup("endOfMibView"); + break; + default: + /* Should not happen in a valid SNMP packet */ + if (asprintf(&str, "[C/%u]", root->be_type) == -1) + goto fail; + break; + } + break; + default: + /* Should not happen in a valid SNMP packet */ + if (asprintf(&str, "[%hhu/%u]", root->be_class, + root->be_type) == -1) + goto fail; + break; + } + + return (str); + + fail: + free(str); + return (NULL); +} + unsigned int smi_application(struct ber_element *elm) { diff --git a/usr.sbin/snmpd/smi.h b/usr.sbin/snmpd/smi.h index 594aededf5a..69bbca8736b 100644 --- a/usr.sbin/snmpd/smi.h +++ b/usr.sbin/snmpd/smi.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smi.h,v 1.1 2022/01/19 10:25:04 martijn Exp $ */ +/* $OpenBSD: smi.h,v 1.2 2022/06/30 09:42:19 martijn Exp $ */ /* * Copyright (c) 2021 Martijn van Duren @@ -25,3 +25,4 @@ char *smi_oid2string(struct ber_oid *, char *, size_t, size_t); u_long smi_getticks(void); char *smi_print_element(struct ber_element *); +char *smi_print_element_legacy(struct ber_element *); diff --git a/usr.sbin/snmpd/snmp.h b/usr.sbin/snmpd/snmp.h index 68502f376f9..9396545617d 100644 --- a/usr.sbin/snmpd/snmp.h +++ b/usr.sbin/snmpd/snmp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: snmp.h,v 1.18 2021/10/21 14:33:13 martijn Exp $ */ +/* $OpenBSD: snmp.h,v 1.19 2022/06/30 09:42:19 martijn Exp $ */ /* * Copyright (c) 2007, 2008, 2012 Reyk Floeter @@ -91,6 +91,12 @@ enum snmp_pdutype { SNMP_C_REPORT = 8 }; +enum snmp_varbindtype { + SNMP_V_NOSUCHOBJECT = 0, + SNMP_V_NOSUCHINSTANCE = 1, + SNMP_V_ENDOFMIBVIEW = 2 +}; + enum snmp_application { SNMP_T_IPADDR = 0, SNMP_T_COUNTER32 = 1, diff --git a/usr.sbin/snmpd/traphandler.c b/usr.sbin/snmpd/traphandler.c index 87ac8066d90..8eb8f3439f2 100644 --- a/usr.sbin/snmpd/traphandler.c +++ b/usr.sbin/snmpd/traphandler.c @@ -1,4 +1,4 @@ -/* $OpenBSD: traphandler.c,v 1.22 2021/10/21 08:17:34 martijn Exp $ */ +/* $OpenBSD: traphandler.c,v 1.23 2022/06/30 09:42:19 martijn Exp $ */ /* * Copyright (c) 2014 Bret Stephen Lambert @@ -380,7 +380,7 @@ trapcmd_exec(struct trapcmd *cmd, struct sockaddr *sa, for (; vb != NULL; vb = vb->be_next) { if (ober_scanf_elements(vb, "{oeS$}", &oid, &elm) == -1) goto out; - if ((value = smi_print_element(elm)) == NULL) + if ((value = smi_print_element_legacy(elm)) == NULL) goto out; smi_oid2string(&oid, oidbuf, sizeof(oidbuf), 0); n = dprintf(s[0], "%s %s\n", oidbuf, value); -- 2.20.1