Rewrite smi_print_element to be more concise and complete.
authormartijn <martijn@openbsd.org>
Thu, 30 Jun 2022 09:42:19 +0000 (09:42 +0000)
committermartijn <martijn@openbsd.org>
Thu, 30 Jun 2022 09:42:19 +0000 (09:42 +0000)
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
usr.sbin/snmpd/smi.h
usr.sbin/snmpd/snmp.h
usr.sbin/snmpd/traphandler.c

index 20471d8..f37443d 100644 (file)
@@ -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 <reyk@openbsd.org>
@@ -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)
 {
index 594aede..69bbca8 100644 (file)
@@ -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 <martijn@openbsd.org>
@@ -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 *);
index 68502f3..9396545 100644 (file)
@@ -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 <reyk@openbsd.org>
@@ -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,
index 87ac806..8eb8f34 100644 (file)
@@ -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 <blambert@openbsd.org>
@@ -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);