ping

On Fri, 2021-05-28 at 08:19 +0200, Martijn van Duren wrote:
> As the original comment said:
> /*
>  * This should probably go into parsevarbinds, but that's for a
>  * next refactor
>  */
> 
> This moves the pdu parsing of traps into parsevarbinds.
> Added bonus, we can now see the packets in debugging mode:
> startup
> snmpe: listening on udp 127.0.0.1:162
> ktable_new: new ktable for rtableid 0
> snmpe_parse: 127.0.0.1:162: SNMPv2 'public' pdutype SNMPv2-Trap request 
> 1329591927
> snmpe_parse: 127.0.0.1:162: SNMPv1 'public' pdutype Trap request 0
> 
> OK?
> 
> martijn@
> 
> Index: snmpd.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/snmpd/snmpd.h,v
> retrieving revision 1.95
> diff -u -p -r1.95 snmpd.h
> --- snmpd.h     20 May 2021 08:53:12 -0000      1.95
> +++ snmpd.h     28 May 2021 06:17:16 -0000
> @@ -776,6 +776,7 @@ int  proc_flush_imsg(struct privsep *, e
>  
>  /* traphandler.c */
>  int     traphandler_parse(struct snmp_message *);
> +int     traphandler_v1translate(struct snmp_message *, int);
>  int     traphandler_priv_recvmsg(struct privsep_proc *, struct imsg *);
>  void    trapcmd_free(struct trapcmd *);
>  int     trapcmd_add(struct trapcmd *);
> Index: snmpe.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/snmpd/snmpe.c,v
> retrieving revision 1.71
> diff -u -p -r1.71 snmpe.c
> --- snmpe.c     20 May 2021 08:53:12 -0000      1.71
> +++ snmpe.c     28 May 2021 06:17:16 -0000
> @@ -368,6 +368,10 @@ snmpe_parse(struct snmp_message *msg)
>                         msg->sm_errstr = "trapv1 request on !SNMPv1 message";
>                         goto parsefail;
>                 }
> +               /* Internally we work with SNMPv2-Traps */
> +               if (traphandler_v1translate(msg, 0) == -1)
> +                       goto fail;
> +               a = msg->sm_pdu->be_sub;
>         case SNMP_C_TRAPV2:
>                 if (msg->sm_pdutype == SNMP_C_TRAPV2 &&
>                     !(msg->sm_version == SNMP_V2 ||
> @@ -390,16 +394,9 @@ snmpe_parse(struct snmp_message *msg)
>                         goto fail;
>                 }
>                 stats->snmp_intraps++;
> -               /*
> -                * This should probably go into parsevarbinds, but that's for 
> a
> -                * next refactor
> -                */
> -               if (traphandler_parse(msg) == -1)
> -                       goto fail;
> -               /* Shortcircuit */
> -               return 0;
> +               break;
>         default:
> -               msg->sm_errstr = "invalid context";
> +               msg->sm_errstr = "invalid pdutype";
>                 goto parsefail;
>         }
>  
> @@ -450,7 +447,14 @@ snmpe_parsevarbinds(struct snmp_message 
>         struct ber_element      *pvarbind = NULL, *end;
>         char                     buf[BUFSIZ];
>         struct ber_oid           o;
> -       int                      i;
> +       int                      i = 1;
> +
> +       if (msg->sm_pdutype == SNMP_C_TRAP ||
> +           msg->sm_pdutype == SNMP_C_TRAPV2) {
> +               if (traphandler_parse(msg) == -1)
> +                       goto varfail;
> +               return 0;
> +       }
>  
>         msg->sm_errstr = "invalid varbind element";
>  
> @@ -458,7 +462,7 @@ snmpe_parsevarbinds(struct snmp_message 
>         msg->sm_varbindresp = NULL;
>         end = NULL;
>  
> -       for (i = 1; varbind != NULL && i < SNMPD_MAXVARBIND;
> +       for (; varbind != NULL && i < SNMPD_MAXVARBIND;
>             varbind = varbind->be_next, i++) {
>                 if (ober_scanf_elements(varbind, "{oeS$}", &o, &value) == -1) 
> {
>                         stats->snmp_inasnparseerrs++;
> @@ -543,7 +547,7 @@ snmpe_parsevarbinds(struct snmp_message 
>         msg->sm_errorindex = 0;
>  
>         return 0;
> - varfail:
> +varfail:
>         log_debug("%s: %s:%hd: %s, error index %d", __func__,
>             msg->sm_host, msg->sm_port, msg->sm_errstr, i);
>         if (msg->sm_error == 0)
> @@ -790,18 +794,18 @@ snmpe_recvmsg(int fd, short sig, void *a
>  void
>  snmpe_dispatchmsg(struct snmp_message *msg)
>  {
> -       if (msg->sm_pdutype == SNMP_C_TRAP ||
> -           msg->sm_pdutype == SNMP_C_TRAPV2) {
> -               snmp_msgfree(msg);
> -               return;
> -       }
>         /* dispatched to subagent */
>         /* XXX Do proper error handling */
>         (void) snmpe_parsevarbinds(msg);
>  
> -       /* respond directly */
> -       msg->sm_pdutype = SNMP_C_GETRESP;
> -       snmpe_response(msg);
> +       if (msg->sm_pdutype == SNMP_C_TRAP ||
> +           msg->sm_pdutype == SNMP_C_TRAPV2)
> +               snmp_msgfree(msg);
> +       else {
> +               /* respond directly */
> +               msg->sm_pdutype = SNMP_C_GETRESP;
> +               snmpe_response(msg);
> +       }
>  }
>  
>  void
> Index: traphandler.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/snmpd/traphandler.c,v
> retrieving revision 1.21
> diff -u -p -r1.21 traphandler.c
> --- traphandler.c       22 Feb 2021 11:31:09 -0000      1.21
> +++ traphandler.c       28 May 2021 06:17:16 -0000
> @@ -45,8 +45,6 @@
>  
>  int     traphandler_priv_recvmsg(struct privsep_proc *, struct imsg *);
>  int     traphandler_fork_handler(struct privsep_proc *, struct imsg *);
> -struct ber_element *
> -        traphandler_v1translate(struct snmp_message *, int);
>  int     trapcmd_cmp(struct trapcmd *, struct trapcmd *);
>  void    trapcmd_exec(struct trapcmd *, struct sockaddr *,
>             struct ber_element *);
> @@ -76,25 +74,17 @@ traphandler_parse(struct snmp_message *m
>         ssize_t                  buflen;
>         int                      ret = -1;
>  
> -       switch (msg->sm_pdu->be_type) {
> -       case SNMP_C_TRAP:
> -               if ((vblist = traphandler_v1translate(msg, 0)) == NULL)
> -                       goto done;
> -               break;
> -       case SNMP_C_TRAPV2:
> -               if (ober_scanf_elements(msg->sm_pdu, "{SSe}$", &elm) == -1) {
> -                       stats->snmp_inasnparseerrs++;
> -                       goto done;
> -               }
> -               if (elm->be_type != BER_TYPE_INTEGER) {
> -                       stats->snmp_inasnparseerrs++;
> -                       goto done;
> -               }
> -               vblist = ober_unlink_elements(elm);
> -               break;
> -       default:
> -               fatalx("%s called without proper context", __func__);
> +       if (ober_scanf_elements(msg->sm_pdu, "{SSe}$", &elm) == -1) {
> +               stats->snmp_inasnparseerrs++;
> +               msg->sm_errstr = "invalid pdu";
> +               goto done;
> +       }
> +       if (elm->be_type != BER_TYPE_INTEGER) {
> +               stats->snmp_inasnparseerrs++;
> +               msg->sm_errstr = "invalid pdu";
> +               goto done;
>         }
> +       vblist = ober_unlink_elements(elm);
>  
>         (void)ober_string2oid("1.3.6.1.2.1.1.3.0", &sysUpTimeOID);
>         (void)ober_string2oid("1.3.6.1.6.3.1.1.4.1.0", &snmpTrapOIDOID);
> @@ -103,11 +93,13 @@ traphandler_parse(struct snmp_message *m
>             ober_oid_cmp(&o1, &sysUpTimeOID) != 0 ||
>             ober_oid_cmp(&o2, &snmpTrapOIDOID) != 0) {
>                 stats->snmp_inasnparseerrs++;
> +               msg->sm_errstr = "invalid pdu";
>                 goto done;
>         }
>         (void)ober_scanf_elements(vblist, "{Se", &elm);
>         for (elm = elm->be_next; elm != NULL; elm = elm->be_next) {
>                 if (ober_scanf_elements(elm, "{oS$}", &o1) == -1) {
> +                       msg->sm_errstr = "invalid pdu";
>                         stats->snmp_inasnparseerrs++;
>                         goto done;
>                 }
> @@ -140,7 +132,7 @@ done:
>         return ret;
>  }
>  
> -struct ber_element *
> +int
>  traphandler_v1translate(struct snmp_message *msg, int proxy)
>  {
>         struct snmp_stats       *stats = &snmpd_env->sc_stats;
> @@ -158,7 +150,8 @@ traphandler_v1translate(struct snmp_mess
>             agent_addrlen != 4 ||
>             vblist->be_type != BER_TYPE_SEQUENCE) {
>                 stats->snmp_inasnparseerrs++;
> -               return NULL;
> +               msg->sm_errstr = "invalid pdu";
> +               return -1;
>         }
>         switch (generic_trap) {
>         case 0:
> @@ -184,33 +177,33 @@ traphandler_v1translate(struct snmp_mess
>                 /* Officially this should be 128, but BER_MAX_OID_LEN is 64 */
>                 if (trapoid.bo_n + 2 > BER_MAX_OID_LEN) {
>                         stats->snmp_inasnparseerrs++;
> -                       return NULL;
> +                       msg->sm_errstr = "enterprise too large";
> +                       return -1;
>                 }
>                 trapoid.bo_id[trapoid.bo_n++] = 0;
>                 trapoid.bo_id[trapoid.bo_n++] = specific_trap;
>                 break;
>         default:
>                 stats->snmp_inasnparseerrs++;
> -               return NULL;
> +               msg->sm_errstr = "invalid generic-trap";
> +               return -1;
>         }
>  
>         /* work aronud net-snmp's snmptrap: It adds an EOC element in vblist 
> */
>         if (vblist->be_len != 0)
>                 vb0 = ober_unlink_elements(vblist);
> +       vblist = ober_unlink_elements(msg->sm_pdu);
> +       ober_free_elements(vblist);
>  
> -       if ((vblist = ober_add_sequence(NULL)) == NULL) {
> -               msg->sm_errstr = strerror(errno);
> -               if (vb0 != NULL)
> -                       ober_free_elements(vb0);
> -               return NULL;
> -       }
> -       if (ober_printf_elements(vblist, "{od}{oO}e", "1.3.6.1.2.1.1.3.0",
> -           time_stamp, "1.3.6.1.6.3.1.1.4.1.0", &trapoid, vb0) == NULL) {
> +       if (ober_printf_elements(msg->sm_pdu, "ddd{{od}{oO}e}", 0, 0, 0,
> +           "1.3.6.1.2.1.1.3.0", time_stamp, "1.3.6.1.6.3.1.1.4.1.0", 
> &trapoid,
> +           vb0) == NULL) {
>                 msg->sm_errstr = strerror(errno);
>                 if (vb0 != 0)
>                         ober_free_elements(vb0);
>                 ober_free_elements(vblist);
> -               return NULL;
> +               msg->sm_errstr = strerror(errno);
> +               return -1;
>         }
>  
>         if (proxy) {
> @@ -220,11 +213,12 @@ traphandler_v1translate(struct snmp_mess
>                     &snmpTrapCommunityOid);
>                 (void)ober_string2oid("1.3.6.1.6.3.1.1.4.3.0",
>                     &snmpTrapEnterpriseOid);
> -               for (elm = vblist->be_sub; elm != NULL; elm = elm->be_next) {
> +               ober_scanf_elements(msg->sm_pdu, "{SSS{e", &elm);
> +               for (; elm != NULL; elm = elm->be_next) {
>                         if (ober_get_oid(elm->be_sub, &oid) == -1) {
>                                 msg->sm_errstr = "failed to read oid";
>                                 ober_free_elements(vblist);
> -                               return NULL;
> +                               return -1;
>                         }
>                         if (ober_oid_cmp(&oid, &snmpTrapAddressOid) == 0)
>                                 hasaddress = 1;
> @@ -243,11 +237,11 @@ traphandler_v1translate(struct snmp_mess
>                             &snmpTrapEnterpriseOid, &enterprise) == NULL) {
>                                 msg->sm_errstr = strerror(errno);
>                                 ober_free_elements(vblist);
> -                               return NULL;
> +                               return -1;
>                         }
>                 }
>         }
> -       return vblist;
> +       return 0;
>  }
>  
>  int
> 


Reply via email to