Is SNMP PDU varbinds order preserved by the snmptrap plugin?

Doesn't seem to... eg v 2c linkUp rubydebug output shown here...

https://www.rfc-editor.org/rfc/rfc3416#page-21
4.2.6. The SNMPv2-Trap-PDU

... The first
** two variable bindings** in the variable binding list of an SNMPv2-
Trap-PDU are sysUpTime.0 [RFC3418] and snmpTrapOID.0 [RFC3418]
respectively. If the OBJECTS clause is present in the invocation of
the corresponding NOTIFICATION-TYPE macro, then each corresponding
** variable**, as instantiated by this notification, is copied, in order,
to the variable-bindings field. ...

In the rudydebug codec output:

...
    "@metadata" => {
        "input" => {
            "snmptrap" => {
                "pdu" => {
                                 "type" => "TRAP",
                          "error_index" => 0,
                    "variable_bindings" => {
                            "1.3.6.1.2.1.1.3.0" => 3310491537,
                          "1.3.6.1.2.1.2.2.1.8" => 1,
                          "1.3.6.1.2.1.2.2.1.1" => 16,
                        "1.3.6.1.6.3.1.1.4.1.0" => "iso.org.dod.internet.snmpV2.snmpModules.snmpMIB.snmpMIBObjects.snmpTraps.linkUp",
                          "1.3.6.1.2.1.2.2.1.7" => 1
                    },
                    "error_status_text" => "Success",
                         "error_status" => 0,
                              "version" => "2c",
                            "community" => "public",
                           "request_id" => 17314
                }
            }
        }
    },
...	
	"message" => "{\"error_index\":0,\"variable_bindings\":{\"1.3.6.1.2.1.2.2.1.7\":1,\"1.3.6.1.2.1.2.2.1.8\":1,\"1.3.6.1.2.1.2.2.1.1\":16,\"1.3.6.1.6.3.1.1.4.1.0\":\"iso.org.dod.internet.snmpV2.snmpModules.snmpMIB.snmpMIBObjects.snmpTraps.linkUp\",\"1.3.6.1.2.1.1.3.0\":3310491537},\"error_status\":0,\"type\":\"TRAP\",\"error_status_text\":\"Success\",\"community\":\"public\",\"version\":\"2c\",\"request_id\":17314}"
...

The varbinds in [@metadata][input][snmptrap][pdu][variable_bindings] in the output above is out-of-order: (the order in "message" seems totally different again)
(sysUpTimeInstance,
ifOperStatus
ifIndex,
snmpTrapOID,
ifAdminStatus)

whereas in IF-MIB:
linkUp NOTIFICATION-TYPE
OBJECTS { ifIndex, ifAdminStatus, ifOperStatus }
STATUS current
DESCRIPTION
"A linkUp trap...."
::= { snmpTraps 4 }

Is there any way to enforce the order of the varbinds so that I can create various field-value processing based on the varbinds defined position?

Thanks.

If you enable debug logging then the input will dump the trap it receives from the underlying Ruby snmp library. If the order has been lost at that point there is nothing logstash can do to restore it.

The input treats the varbinds as a hash, so it should preserve order, The underlying library seems to know it is an ordered sequence, but I cannot speak to what that code does.

Hi Badger, thanks for the direction!

From the logstash debug log: VBS[...] shows the varbinds order in the PDU to be correct as expected:

[2025-05-01T11:22:29,426][DEBUG][org.logstash.snmp.SnmpClient][main] SNMP Trap received: CommandResponderEvent[securityModel=2, securityLevel=1, maxSizeResponsePDU=65512, pduHandle=PduHandle[951], stateReference=StateReference[msgID=0,pduHandle=PduHandle[951],securityEngineID=null,securityModel=null,securityName=public,securityLevel=1,contextEngineID=null,contextName=null,retryMsgIDs=null], pdu=TRAP[requestID=951, errorStatus=Success(0), errorIndex=0, VBS[1.3.6.1.2.1.1.3.0 = 384 days, 2:50:53.03; 1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.6.3.1.1.5.4; 1.3.6.1.2.1.2.2.1.1 = 16; 1.3.6.1.2.1.2.2.1.7 = 1; 1.3.6.1.2.1.2.2.1.8 = 1]], messageProcessingModel=1, securityName=public, processed=false, peerAddress=192.168.0.90/62678, transportMapping=org.snmp4j.transport.DefaultUdpTransportMapping@3e36c3a7, tmStateReference=TransportStateReference[transport=org.snmp4j.transport.DefaultUdpTransportMapping@3e36c3a7, address=0.0.0.0/162, securityName=null, requestedSecurityLevel=undefined, transportSecurityLevel=undefined, sameSecurity=false, sessionID=java.net.DatagramSocket@2a04deb1, target=null]]

In stdout rubydebug [@metadata] and a custom field [snmptrapvarbinds] (set by target => "snmptrapvarbinds" in the snmptrap plugin),

however, the varbinds order in @metadata is different to that in debug log PDU dump.
Actually, the order in this @metadata is different from that in my yesterday's post too! Which suggests the order in @metadata is quite random!

Furthermore, the snmptrap plugin copy the varbinds to the custom field in yet another different and random order. However, this order in the custom field did get preserve when output to Elasticsearch as shown here too. Looks like I am out of luck here as you mentioned there is nothing logstash can do now :frowning: Anyway, just share this outcome in case anyone interested.

    "@metadata" => {
        "input" => {
            "snmptrap" => {
                "pdu" => {
                            "community" => "public",
                         "error_status" => 0,
                           "request_id" => 951,
                    "variable_bindings" => {
                        "1.3.6.1.6.3.1.1.4.1.0" => "IF-MIB::linkUp",
                            "1.3.6.1.2.1.1.3.0" => 3318785303,
                          "1.3.6.1.2.1.2.2.1.1" => 16,
                          "1.3.6.1.2.1.2.2.1.7" => 1,
                          "1.3.6.1.2.1.2.2.1.8" => 1
                    },
                    "error_status_text" => "Success",
                          "error_index" => 0,
                                 "type" => "TRAP",
                              "version" => "2c"
                }
            }
        }
    },

    "snmptrapvarbinds" => {
                  "SNMPv2-MIB::snmpTrapOID.0" => "IF-MIB::linkUp",
                            "IF-MIB::ifIndex" => 16,
                      "IF-MIB::ifAdminStatus" => 1,
        "DISMAN-EVENT-MIB::sysUpTimeInstance" => 3318785303,
                       "IF-MIB::ifOperStatus" => 1
    },

In ES/Kibana:

    "snmptrapvarbinds": {
      "SNMPv2-MIB::snmpTrapOID.0": "IF-MIB::linkUp",
      "IF-MIB::ifIndex": 16,
      "IF-MIB::ifAdminStatus": 1,
      "DISMAN-EVENT-MIB::sysUpTimeInstance": 3318785303,
      "IF-MIB::ifOperStatus": 1
    },

-end-