Skip to main content

SNMP Trapd LAMbot v2 Additional Notes

Notice

See Installing SNMP Trapd v2 for instructions on obtaining and installing SNMP Trapd v2.

An updated version of the SNMP Trapd LAM was released in Add-Ons 2.4, including LAMbot, utilities, include files and modules in the MoogTrapdLamV2.tar.gz archive.

The archive contains the following files:

bots/lambots/MoogTrapdLamV2.js
bots/lambots/trapModules/master.includes
bots/lambots/trapModules/<vendor> 
contrib/TrapUtiity.js
config/moog_trapd_lamV2.conf
mib2lam/

Working with Microfocus / NP NNMi

If HP/MF NNMi is part of the data pipeline and forwards traps from NNMi to Moogsoft (as SNMP traps), the TrapLamV2 LAMbot needs to be configured to interpret these traps to accommodate the non-RFC way in which NNMi forward traps. NNMi does not use the RFC compliant mechanism for specifying the original source of a trap (snmpTrapAddress), instead it uses an HP specific OID (originIPAddress).

In the LAMbot add the following line after the trapUtil.init() statement.

trapUtil.setNNMiForwarded(true);

Incoming traps will be examined for the originIPAddress varbind, and if present, this will be used to set the source of the trap.

Working with partially translated payload values for indirect traps

Some systems that may send indirect traps to Moogsoft may also partially or fully translate OIDs to MIB-Object names, and these need to be reverse translated to OIDs to allow the standard trap processing using the include file to function.

  • Translation to a single item (with or without index) e.g. “ifIndex.123” rather than a compound item e.g “IF-MIB::ifIndex.123”, will require additional logic to determine the required OID, since duplicate names are valid (i.e. multiple MIBs may contain an “ifIndex” object).

  • Partial translation to a module and object is more common e.g. SNMPv2-SMI::enterprises.116.5.11.4.2.7

Where either full or partial translation is in place, the LAMbot should attempt to reverse translate these values to raw OIDs.

Partial translation

Given an OID of

SNMPv2-SMI::enterprises.116.5.11.4.2.7

We can interpret this as “the enterprises object in the SNMPv2-SMI MIB module” + 116.5.11.4.2.7

To reverse translate this we would use the Trap utility reverseTranslate() function. This expects a string to be passed in the forma of:

reverseTranslate('MIB-MODULE::mib-Object.mib-index = "<value>"')

Note

This format is the most common pattern and the reverseTranslate() function enforces it - if your data is in a different format, then it may need to be manipulated before using the reverseTranslate() function.

For example, given a varbind in a payload of:

"SNMPv2-SMI::enterprises.116.5.11.4.2.6" : "A value for eventTrapTime"

We would use the following to reverse translate this:

var translated = trapUtil.reverseTranslate('"SNMPv2-SMI::enterprises.116.5.11.4.2.6" = "A value for eventTrapTime"')

This would return an object (translated) of :

{
    "oid": "1.3.6.1.4.1.116.5.11.4.2.6",
    "value": "A value for eventTrapTime\" ",
    "mib": "SNMPv2-SMI",
    "index": "116.5.11.4.2.6"
}

This data would then be used with the addVarbind() function to add the oid and value to the trap.

trap.addVarbind(translated.oid,translated.value);

Enumerated values

When the reverse translation process finds an enumeration, the process will try and also translate this enumeration into the appropriate numeric value. For example, given a partially translated value of:

{ 
  ...
  "IF-MIB::ifType.1" : "ethernetCsmacd"
  ...
}

We’d get a translated value of:

trapUtil.reverseTranslate('IF-MIB::ifType.1 = "ethernetCsmacd"');

{
    "oid": "1.3.6.1.2.1.2.2.1.3.1",
    "value": "6",
    "mib": "IF-MIB",
    "index": "1"
}

The value has ben enumerated to the matching value in the IF-MIB (derived from the IANAifType-MIB).

Working with fully translated objects

If an indirect source has fully translated the MIB object to a single object name, then there is the risk that there is more than one mib object has the same name. For example the following two MIB definitions both have the same name “eventSummary” - but these have very different OIDs.

AVAMAR-MCS-MIB
...
eventSummary OBJECT-TYPE
    SYNTAX DisplayString (SIZE (0..256))
    ACCESS read-only
    STATUS mandatory
    DESCRIPTION "One line summary description of event reported"
  ::= { eventData 5 }
KASHYA-MIB
...
    eventSummary OBJECT-TYPE
        SYNTAX              OCTET STRING
        ACCESS              read-only
        STATUS              mandatory
        DESCRIPTION         "Short description of event."
        ::= { trapInfo 10 }

If we were presented with a indirect payload with a fully translated name for this with no MIB context, it would not be possible to use the reverseTranslate() directly. There is no not enough context to narrow down the object to a specific MIB and resulting OID.

{
  ...
  "eventSummary" : "This is a test event"
  ...
}

In cases like this additional logic will be needed to get all possible values for the mib object - and determine which of these is appropriate.

To fetch all known details for a mib object (by name only) use the Trap utility - findMibObject() function.

var allObjects = trapUtil.findMibObject("eventSummary");

Would return

[
    {
        "parent_name": "eventData",
        "current": true,
        "mib_name": "AVAMAR-MCS-MIB",
        "name": "eventSummary",
        "syntax": {
            "name": "DisplayString",
            "raw": "DisplayString"
        },
        "oid_path": "1.3.6.1.4.1.15597.1.1.1.2.5",
        "isTrap": false
    },
    {
        "parent_name": "trapInfo",
        "current": true,
        "mib_name": "KASHYA-MIB",
        "name": "eventSummary",
        "syntax": {
            "name": "OCTET STRING",
            "raw": "OCTET STRING"
        },
        "oid_path": "1.3.6.1.4.1.21658.3.1.1.10",
        "isTrap": false
    }
]

The data returned can be used to determine which of the objects to use - for example comparing the oid_path in the returned data with other oid data (e.g. the snmpTrapOID) to see if there shared a common stem, enterprise number etc.

This conflict resolution needs to be accurate, if the wrong OID is passed to the processing, then the resulting event may have incomplete data.

TrapUtility functions

  • Trap class

    • setSnmpVersion() - set the SNMP version (1, 2|2c, 3) for the trap.

    • setSpecificCode(<integer>) - set the specific code for a v1 trap object.

    • setGenericCode(<integer> )- set the generic code for a v1 trap object.

    • setSource(host) - set the source for the trap object.

    • setEnterprise(oid) - set the enterprise for a v1 trap object.

    • setSnmpTrapOID(oid) - set the snmpTrapOID value for a v2c/3 trap object.

    • setSnmpTrapAddress(ipAddress) - set the source varbind for a v2c/3 trap - e.g. in the case of a forwarded trap.

    • addVarbind(oid,value) - add a varbind to a trap object.

    • validate() - validate the trap object has sufficient data to proceed.

    • processTrap() - process the trap object via the appropriate include file. This includes all the required routing etc. (calls processSNMPTrap())

  • TrapUtility functions - the majority of these are internal utility functions and do not be called directly as part of any ingestion.

    • init(moduleFile) - initialise the Trap Utility passing the master.includes file.

    • processSNMPTrap(trapObject) - process the trap.

    • prepareEvent(moogEvent) - prepare the event from the include file for despatch .

    • isOID(string) - returns true if the passed string is a recognised OID.

    • trimOID(oid) - remove leading/trailing spaces and leading “.” from an OID.

    • expandOID(oid,isEnterprise) - convert an OID into a textual representation of that OID. If isEnterprise is passed as true, then convert only the portion of the OID after the enterprises prefix.

    • contractOID([list], isEnterprise) - convert a fully translated OID (e.g. [ “iso”, “org” , “dod” , “internet” …. ]) to an OID.

    • validateModule(moduleKey) - used in processing a trap object.

    • getTrapModule(trapInfo, trapData) - from the available data find the appropriate module that should process the trap object.

    • dnsLookup(ipAddress) - perform a DNS lookup of an IP address.

    • normaliseTrap(trapData) - normalise a v1/v2c/v3 trap into a common data structure for processing by the include.

      • normaliseV1trap() - v1 normalisation

      • normaliseV2trap() - v2c/3 normalisation.

    • extractNNMiAgent() - part of the NNMi processing flow (See above)

    • setTrapData(overflow) - set trap data.

    • setTrapDebug(true|false) - enables or disables trapDebug - controls the level of detail logged to the LAM log and the level of data included in the resulting event (include or exclude source data).

    • setV2Forwarded(true|false) - sets the is V2 forwarded flag - should be set if using a v2 forwarding mechanism.

    • setNNMiForwarded(true|false) - sets the NNMi processing flag (see above).

    • logTrapRoutes() - Add debug to the lam startup to list the trap routes that are configured.

    • logTrapModules() - Add debug to the lam startup to list list the modules that are loaded.

    • Set Defaults for all events processed by this LAM

      • setDefaultClass(class)

      • setDefaultAgent(agent)

      • setDefaultManager(manager)

      • setDefaultValue(value) - the value to use if no other is found for a core field.

      • setDefaultSeverity(severity) - set the default severity if none was found.