SNMP-TRAP

Note

For SNMP GET/SET see SNMP

Capabilities

Capabilities

Support v1

Support v2c

Support v3

Comment

SNMP GET/SET

N.A.

N.A.

N.A.

See SNMP

SNMP over UDP

Supported feature

Supported feature

Supported feature

SNMP over TCP

Not supported feature

Not supported feature

Not supported feature

SNMP over IPv6

Not supported feature

Not supported feature

Not supported feature

Use rules on the docker-host to convert to IPv4

Trap reception/manipulation

Supported feature

Supported feature

Supported feature

Inform reception/manipulation

Not supported feature

Supported feature

Supported feature

Security Model

Not supported feature

Not supported feature

Supported feature

User Security Model (USM)

Authentication

Not supported feature

Not supported feature

Supported feature

MD5, SHA, HMAC_128-SHA_224, HMAC_192-SHA_256, HMAC_256-SHA_384, HMAC_384-SHA_512

Encryption

Not supported feature

Not supported feature

Supported feature

DES, AES_128, IDEA, AES_192, AES_256, AES_128_W_3_DES_KEY_EXT, AES_192_W_3_DES_KEY_EXT, AES_256_W_3_DES_KEY_EXT

Discovery

Not supported feature

Not supported feature

Supported feature

The engineId, engineBoot and engineTime can be discovered by using an empty request as define on the RFC 3414.

Note

A compatibility mode is available to change the behavior of the discovery process.

By default, the discovery will send the engineId on the first request and send the engineTime and engineBoot on a second request with a valid authentication.

When the compatibility mode is enable, the engineBoot and engineTime will be sent a the same time as the engineId.

Examples

Concept

Overview

Note

In the following documentation, the terminology SNMP messages (or message) will be used to describe both Trap and Info (Inform messages are basically acknowledged Traps). If an explanation relates to only one of those then the explicit terminology (Trap or Inform) is used.

OnSphere is able to listen for incoming SNMP messages, make them available inside a flexible / safe / enriched scripting context for you to manipulate and eventually request the generation of a custom tailored alarms based on it. SNMP v3 security features are handled at the configuration level so that you can deal with it once and for all then manipulate v3 messages in the scripting context as you would with v1 and v2 messages.

Note

Reception of 1 SNMP message can lead to generation of 1 alarm at most (0 or 1).

OnSphere allows you to serialize every network packet received on the port configured for SNMP message reception in a pcap format so that you can analyze it later at your convenience. A default provided tool let you replay those file so that you can reproduce scenario and better configure your system.

Usage

  • Network devices monitoring

How it is done

SNMP Message reception

Reception of SNMP messages is done by listening on configured UDP port (This is configured on the osp-snmp-trap and Modify the configuration of a service file).

The SNMP must keep the client address, as the docker overlay network do NAT, we must change the configuration of the osp-snmp-trap container to use a host network.

Warning

This means it is only possible to have one instance of osp-snmp-trap module by node.

Network traffic serialization

Warning

Network packets serialization is an heavy operation for the file system. Be aware that enabling this feature has a cost, mainly in high-speed systems.

If you decide to enable (serialization.enable) traffic serialization, OnSphere’s configuration exposes other parameters (serialization.maxTrapPerFile / serialization.maxSizeMo) allowing file rotation so that you can beneficiate from packets serialization without having to worry about filling up disk space.

The rotation policy is as follow:

Note

Configured maximum size in Mo is only evaluated when a rotation or restart is triggered meaning it can be exceeded if the configured maximum number of SNMP message per file is very high.

Warning

Never remove the current traps.pcap file while the osp-snmp-trap module is running

Serialized traffic is stored at /serialize on the osp-snmp-trap module’s container. It can be freely mounted as a volume in docker compose on your host. Otherwise, you can copy files with :

docker cp [docker-id]:/serialization/[file-name].pcap [local-path]

To add the serialization volume mount inside the module.service of the osp-snmp-trap module’s container :

(to mount in /opt/osp/on-host/serialization, provided it exist on the host)

${{service-name}}:
image: ${{image-repository}}osp-snmp-trap${{image-version}}
volumes:
  - /opt/osp/on-host/serialization/:/serialization
networks:
  - "back"
  - "outside_access"
ports:
  - published: 162
    target: 10162
    protocol: udp
    mode: host
secrets:
  - ${{auto-generated-secret-access}}

Warning

Always use a replicated disk or be sure the folder exist on all hosts to avoid loosing traps if the service is moved from one host to another

Safe / enriched / flexible scripting context

The scripting context can be exploited through Lua rules (which must be registered as resources). Rules allow inspection of the incoming SNMP message in order to either discard it or use its information to enrich resulting alarm. Every received message accepted (SNMP v3 requires messages to comply with configured security parameters) are fed to the rules. Rules will then either transform the given message into an alarm or discard it.

Note

The rules entrypoint is a main function with main(trap, alarm) signature. This main method MUST BE PROVIDED for the system to work.

Safe

The scripting context has been made as safe as possible by:

  • limiting possible function calls to avoid damaging the container or the host it is running on

  • wrapping executions so that potential scripting errors don’t crash the whole module.

While usage of this scripting context is protected to avoid major issues for default provided functions most of the time efficiency has been favored over safety. To better understand what it means and how to switch the focus on safety some examples are provided :

-- Due to efficiency concerns, default provided methods are not as protected as they could. 

-- E.g : method helper_get_oid_last_digit(oid) expects the oid parameter to be a string composed of multiple digits
-- separated by dots. If provided prameter is not of type string or not composed of digits, or if those digits are not
-- separeted by dots then the method will fail with an error message which can often be confusing. If you favor ease of
-- integration over efficiency then you should add some checks:

-- helper_get_oid_last_digit(oid) could become helper_safe_get_oid_last_digit(oid):

function helper_safe_get_oid_last_digit(oid)

    -- Check provided param is a string
    if type(oid) ~= TYPE_STRING then
        log("[helper_safe_get_oid_last_digit] : Invalid method call, provided oid must be of type string")
    end

    -- Check provided param contains dots
    -- ....
    -- Check provided param does not end with a dot
    -- ....
    -- Check value after last dot is a digit
    -- ....
    -- Check ....

    helper_get_oid_last_digit(oid)
end
Enriched

To ease and shorten configuration time the scripting context has been enriched by injecting functions and class helper.

Note

Before making use of the scripting context you should be familiar with Lua features among which:

  • it is customary in Lua to start indexes at 1

  • variables are not strongly typed (ie. it is possible to create a variable captainAge in which you could store 42 (an integer) as well as too old to care (a string))

  • everything that is not declared local (variables as well as functions) is available globally (i.e across every rules files). While it can be the desired behavior, it should be done with extreme caution as it means it can be modified from anywhere

  • methods which can be access through : can also be accessed through .. The : syntax is only an object-oriented syntactic sugar (e.g: trap.bindings:size() <=> trap.bindings.size(trap.bindings) )

Default provided functions and class

So that you don’t have to reinvent the wheel each and every time, OnSphere provides by default some helper objects and functions.

Default provided objet:

The rules entry point is the main method which takes two parameters:

  • trap

  • alarm

trap

Note

For retro-compatibility purposes, the trap object available in Lua scripts is used to manipulate bot Trap and Inform messages. The type of the message can be retrieved using trap.type

This is the variable representing received SNMP message. It has the following attributes:

Field

Type

Description

trap.type

String

The SNMP message type (can be either TRAP or INFORM).

trap.oid

String

The SNMP message OID (Object IDentifier).

trap.occurrence

Number

The time at which the message was received by the module.

trap.community

String

The community name.

trap.version

Number

The SNMP version of the message.

trap.source_address

String

The IP address from which the message was sent.

trap.source_port

Number

The port used to send the message.

trap.destination_address

String

The IP address on which the message was received.

trap.destination_port

Number

The port on which the message was received.

trap.bindings

List<Binding>

The variable bindings (pairs [OID/value]) of the message.

trap.v1_specific_fields

Object

Fields which are specific to v1 trap.

trap.v3_specific_fields

Object

Fields which are specific to v3 messages.

Note

The version field can have the following values:

  • 0 : SNMP v1

  • 1 : SNMP v2c

  • 2 : SNMP v2stern

  • 3 : SNMP v3

Messages of different versions might not have the same fields. E.g an SNMP v1 message will have a specific-trap field which later version messages will not. To get the “equivalent” some computing might be needed. While it will always depend on what has been implemented on the infrastructure, RFC 2576 has been especially written to describe “coexistence between version 3 of the Internet-standard network Management Framework, (SNMPv3), version 2 of the Internet-standard Network Management Framework (SNMPv2), and the original Internet-standard Network Management Framework (SNMPv1)”. Some ready-to-use helpers for this are available in default-functions/snmp-trap/helpers by checking out the origin/osp-snmp-trap-configuration branch.

Warning

It is important to take into account the type of each field to avoid undesired comparison result. E.g the version is stored in a Number which means the following statement will always be true: if (trap.version ~= "2")

Trap’s binding

Binding have the following field:

Field

Description

binding.oid

OID of the binding

binding.value

Value of the binding

binding.raw_value

Value of the binding as a list of bytes

binding.PROPERTY_X

Value of the binding X property

The raw_value is only populated when the value contains the character $ which is used to replace non printable character. The raw_value can be used to generate a proper UTF-8 string using default provided convert_encoding function.

Properties are used when a MIB is applied on bindings. If a translation is found for an OID of a binding then a new property is added so that binding.translated_oid = OID_TRANSLATION

E.g: if an SNMP message has a binding whose OID is 1.3.6.1.2.1.1.3.0 (standard OID for system uptime), when a MIB will be applied on this binding then a new property will be added so that : binding.translated_oid = sysUpTime

To keep the scripting context as flexible as possible binding’s properties are dynamic and can be added by users so that you can do :

bindings[binding.translated_oid] = binding.value

Doing so would allow in the previous example to access the system uptime with : binding.sysUpTime

Note

Some ready-to-use helpers for bindings manipulation are provided if needed.

Trap’s v1 specific fields

For v1 SNMP messages, v1_specific_fields has the following attributes:

Field

Type

Description

v1_specific_fields.specific_trap

String

Specific-trap field of SNMPv1

v1_specific_fields.enterprise

String

Enterprise field of SNMPv1

Note

For v2 and v3 messages, v1_specific_fields parameter will still be available (i.e different of nil) even though its values might not make sens (i.e specific_trap will be set with the last digit of the trap.oid parameter and enterprise will be empty)

SNMP message v3 specific fields

For v3 messages, v3_specific_fields has the following attributes:

Field

Type

Description

v3_specific_fields.is_authenticated

Boolean

True if the message has been authenticated according to the USM matching the message security name

v3_specific_fields.user_security_name

String

The security name of the user used to send the message

v3_specific_fields.engine_id

String

The message engine id (engine id of the sender in case of trap, engine id of the snmp-trap module in case of inform)

v3_specific_fields.context_name

String

The message contextName decoded to ASCII

v3_specific_fields.raw_context_name

Byte[]

The message raw contextName only when the $ is present on the ASCII

The raw_context_name is only populated when the context_name contains the character $ which is used to replace none printable character. The raw_context_name can be used with convert_encoding to generate a proper UTF-8 string.

Note

For message with a version other than 3, the v3_specific_fields is nil

alarm

This is the variable representing the alarm which will be published on the OnSphere communication bus if you decide not to discard received SNMP message. It has the following attributes:

Field

Type

Description

alarm.uid

String

The alarm unique identifier (read only).

alarm.occurrence

Number

The moment the alarm was created (read only)

alarm.summary

String

The alarm summary.

alarm.severity

Number or String

The alarm severity (numeric value or the itemId of the severity).

alarm.source

String

Name of the alarm source (i.e. the SNMP message sender).

alarm.location

String

An identifier of the item related to the alarm.

alarm.serial

String

Field used for alarm deduplication (i.e. all alarms with same serial content will be merged).

alarm.tags

List<String>

An array of tags associated with the alarm.

alarm.additionalData

Map<String, Object>

Any other useful information as a map of key/value pair.

alarm.storeRawData

Boolean

Specify if the raw data forming the trap should be stored for later replay

Any information you want to attach to the alarm which does not already have a field should be stored in the alarm.additionalData field.

E.g :

alarm.additionalData["description"] = "This is an alarm description"
Default provided functions:
Discard function

The discard function allows you to exit rules processing when you identified received SNMP message will not need for an alarm to be published on the OnSphere communication bus. It takes no argument it is simply called as follow:

discard()

For efficiency purposes you should aim at calling it as soon as possible as it will avoid any un-necessary processing.

Trap manipulation

The trap object is the main object. Its content will allow you decide if an alarm needs to be published and let you properly build said alarm if so. To help you manipulate the trap object some functions are provided :

-- Attention, all these methods come from the git snmp-trap-default-functions.
-- It is recommended not to modify these files and to add similar functions with different behavior if necessary.
-- In case of edition, there will be need manually merge from snmp-trap-default-functions when upgrading to newest versions.


function print_trap_info(trap, logLevelInput)
    local logLevel = "INFO"

    if (logLevelInput ~= nil) then
        logLevel = logLevelInput;
    end

    local logEntries = {
        "-- New TRAP is received",
        "SnmpMsg oid               : " .. tostring(trap.oid),
        "SnmpMsg type              : " .. tostring(trap.type),
        "SnmpMsg occurrence        : " .. tostring(trap.occurrence),
        "Community name            : " .. tostring(trap.community),
        "Snmp version              : " .. tostring(trap.version),
        "Source                    : " .. tostring(trap.source_address) .. ":" .. tostring(trap.source_port),
        "Destination               : " .. tostring(trap.destination_address) .. ":" .. tostring(trap.destination_port),
    }

    if (trap.v1_specific_fields.specific_trap ~= "") then
        table.insert(logEntries, "Specific-trap            : " .. tostring(trap.v1_specific_fields.specific_trap))
    end
    if (trap.v1_specific_fields.enterprise ~= "") then
        table.insert(logEntries, "Enterprise               : " ..  tostring(trap.v1_specific_fields.enterprise))
    end

    if (trap.v3_specific_fields ~= nil) then
        table.insert(logEntries, "Authenticated            : " ..  tostring(trap.v3_specific_fields.is_authenticated))
        table.insert(logEntries, "UserSecurityName         : " ..  tostring(trap.v3_specific_fields.user_security_name))
        table.insert(logEntries, "EngineId                 : " ..  tostring(trap.v3_specific_fields.engine_id))
        table.insert(logEntries, "ContextName              : " ..  tostring(trap.v3_specific_fields.context_name))
    end

    table.insert(logEntries, "SnmpMsg variables bindings : ")
    for index, binding in ipairs(trap.bindings) do
        if (binding.translated_oid ~= nil) then
            table.insert(logEntries, " - " .. tostring(binding.oid) .. " / " .. tostring(binding.translated_oid) .. " : " .. tostring(binding.value))
        else
            table.insert(logEntries, " - " .. tostring(binding.oid) .. " : " .. tostring(binding.value))
        end
        if (binding.properties:size() ~= 0) then
            table.insert(logEntries, "\t* binding properties : ")

            for property_name, property_value in pairs(binding.properties) do
                table.insert(logEntries, "\t\t- " .. tostring(property_name) .. " : " ..  tostring(property_value))
            end
        end
    end

    log(logLevel, table.concat(logEntries, "\n"))
end
SNMP version tools

It is possible the infrastructure you are working in is using different versions of SNMP. To help you make those different versions coexist some functions are provided :

-- Attention, all these methods come from the git snmp-trap-default-functions.
-- It is recommended not to modify these files and to add similar functions with different behavior if necessary.
-- In case of edition, there will be need manually merge from snmp-trap-default-functions when upgrading to newest versions.

--- Method to compute the equivalent of the (v1) enterprise field out of a v2 trap given the trap and its trap OID
--@param trap The trap from which the equivalent of the (v1) enterprise field must be computed
--@param trapOid The OID of the trap from which the equivalent of the (v1) enterprise field must be computed
--@return The equivalent of the (v1) enterprise field computed from a v2 trap as defined by the standard
--@see https://datatracker.ietf.org/doc/html/rfc2576
function helper_get_v1_enterprise_field_from_v2_trap(trap, trapOid)

    local enterprise = ""

    if string.sub(trapOid, 1, string.len(STANDARD_TRAPS_OID_START)) == STANDARD_TRAPS_OID_START then -- SNMPv2 snmpTrapOID parameter is one of the standard traps

        local optBindingVal = helper_get_value_of_binding_with_oid_as(trap.bindings, OID_TRAP_ENTERPRISE_ZERO, TYPE_STRING)
        if optBindingVal ~= nil and optBindingVal ~= TYPE_STRING_DEFAULT_VAL then
           enterprise = optBindingVal
        else
            enterprise = "snmpTraps"
       end

    else -- SNMMPv2 snmpTrapOID parameter is not one of the standard traps

        local nextToLastSubIdentifier = helper_get_oid_next_to_last_sub_identifier(trapOid)
        local subIdentifiers = helper_get_oid_sub_identifiers(trapOid)
        local numberOfSubIdentifiers = helper_get_table_length(subIdentifiers)

        table.remove(subIdentifiers) 
        if nextToLastSubIdentifier == "0" then -- next-to-last sub-identifier of the snmpTrapOID is 0
            table.remove(subIdentifiers) 
            enterprise = helper_create_oid_from_sub_identifiers(subIdentifiers)
        else -- next-to-last sub-identifier of the snmpTrapOID is NOT 0
            enterprise = helper_create_oid_from_sub_identifiers(subIdentifiers)
        end
    end

    return enterprise
end

--- Method to compute the equivalent of the (v1) specific trap code out of a v2 trap given its OID
--@param trapOid the OID of the trap from which the equivalent of the (v1) specific trap code must be computed
--@return The equivalent of the (v1) specific trap code computed from the given v2 trap's OID
--@see https://datatracker.ietf.org/doc/html/rfc2576
function helper_get_v1_specific_trap_field_from_v2_trap(trapOid)
   
    if string.sub(trapOid, 1, string.len(STANDARD_TRAPS_OID_START)) == STANDARD_TRAPS_OID_START then -- SNMPv2 snmpTrapOID parameter is one of the standard traps
        return 0
    else -- SNMMPv2 snmpTrapOID parameter is not one of the standard traps
        return helper_get_oid_last_digit(trapOid)
    end
    
end
Trap’s bindings manipulation

Most information useful to decide wether or not an alarm should be created, and if so, which information it should contains, are stored in bindings. To help you manipulate those bindings some functions are provided :

-- Attention, all these methods come from the git snmp-trap-default-functions.
-- It is recommended not to modify these files and to add similar functions with different behavior if necessary.
-- In case of edition, there will be need manually merge from snmp-trap-default-functions when upgrading to newest versions.


--- Method to fetch the OID of a binding at a specific index in a list of bindings
--@param bindings The bindings to search (as provided by trap.bindings)
--@parm  index The index of the binding whose OID is targeted
--@return The OID of the binding located at the provided index in the given bindings list or TYPE_STRING_DEFAULT_VAL if no binding is found at this index
function helper_get_oid_of_binding_at_index(bindings, index)
    for current_binding_index, binding in ipairs(bindings) do
      if current_binding_index == index then
        return binding.oid
      end
    end
    return TYPE_STRING_DEFAULT_VAL
end

--- Method to fetch the value (as a given type) of the binding targeted by its OID among a list of bindings
--@param bindings The bindings to search (as provided by trap.bindings)
--@param oid The OID of the binding whose value is targeted
--@param type The type in which the targeted value will be returned
--@return The value (formated in the given type) of the binding whose OID is provided, found among the given bindings list or if not found, if the provided type exists then its default value is returned. Otherwise a nil value is returned
function helper_get_value_of_binding_with_oid_as(bindings, oid, type)
    for _, binding in ipairs(bindings) do
      if binding.oid == oid then
        return helper_check_and_change_type(binding.value, type)
      end
    end
    if type == TYPE_STRING then
        return TYPE_STRING_DEFAULT_VAL
      elseif type == TYPE_NUMBER then
        return TYPE_NUMBER_DEFAULT_VAL
      elseif type == TYPE_BOOLEAN then
        return TYPE_BOOLEAN_DEFAULT_VAL
      end
      return nil
end

--- Method to fetch the value (as a given type) of the binding at a specific index in a list of bindings
--@param bindings The bindings to search (as provided by trap.bindings)
--@param index the index of the binding whose value is targeted
--@param type the type in which the targeted value will be returned
--@return The value (formated in the given type) of the binding located at the provided index in the given bindings list or, if no binding is found with this index, but the type exist, the type's default value, otherwise a nil value.
function helper_get_value_of_binding_at_index_as(bindings, index, type)
  for current_binding_index, binding in ipairs(bindings) do
    if current_binding_index == index then
      return helper_check_and_change_type(binding.value,type)
    end
  end
  if type == TYPE_STRING then
    return TYPE_STRING_DEFAULT_VAL
  elseif type == TYPE_NUMBER then
    return TYPE_NUMBER_DEFAULT_VAL
  elseif type == TYPE_BOOLEAN then
    return TYPE_BOOLEAN_DEFAULT_VAL
  end
  return nil
end

function vb_exists(v)
  return v ~= nil
end

-- deprecated
function get_value_of_binding_with_oid(bindings, targeted_oid)
  return helper_get_value_of_binding_with_oid(bindings, targeted_oid)
end


function helper_get_value_of_binding_with_oid(bindings, targeted_oid)
  for index, binding in ipairs(bindings) do
      if binding.oid == targeted_oid then
          return binding.value
      end
  end
  return nil
end
MIB usage

MIBs are very useful to be able to manipulate trap’s bindings with a clear and explicit name rather than with an obscure OID. To help you use MIBs some functions are provided :

-- Attention, all these methods come from the git snmp-trap-default-functions.
-- It is recommended not to modify these files and to add similar functions with different behavior if necessary.
-- In case of edition, there will be need manually merge from snmp-trap-default-functions when upgrading to newest versions.

--- Method to enrich a list of bindings by applying a MIB on it
--@param mibname The name of the MIB to use to enrich the bindings
--@param bindings The list of bindings to enrich with the MIB
--@return The bindings enriched with the information contained in the specified MIB
function apply_mib(mibname, bindings)
    for index, binding in ipairs(bindings) do
        local translatedOid = lookup(mibname, binding.oid)
            if (translatedOid ~= nil) then
                binding.translated_oid = translatedOid
            end
    end
    return bindings
end
Alarm manipulation

The main purpose of this module is to eventually publish an alarm on the OnSphere communication bus. To help you manipulate this alarm some functions are provided :

-- Attention, all these methods come from the git snmp-trap-default-functions.
-- It is recommended not to modify these files and to add similar functions with different behavior if necessary.
-- In case of edition, there will be need manually merge from snmp-trap-default-functions when upgrading to newest versions.


function print_alarm_info(alarm, logLevelInput)
    local logLevel = "INFO"

    if (logLevelInput ~= nil) then
        logLevel = logLevelInput;
    end

    local logEntries = {
        "\tAlarm",
        "UID            : " .. tostring(alarm.uid),
        "Occurrence     : " .. tostring(alarm.occurrence),
        "Summary        : " .. tostring(alarm.summary),
        "Location       : " .. tostring(alarm.location),
        "Severity       : " .. tostring(alarm.severity),
        "Source         : " .. tostring(alarm.source),
        "Serial         : " .. tostring(alarm.serial),
        "Tags\t: "
    }

    for i=1,alarm.tags:size() do
        table.insert(logEntries, " - "  .. tostring(alarm.tags[i]))
    end
    table.insert(logEntries, "Additional info : ")

    for key, val in pairs(alarm.additionalData) do
        table.insert(logEntries, " - " .. key .. " : " ..  tostring(val))
    end

    log(logLevel, table.concat(logEntries, "\n"))
end
OID manipulation

OIDs are widely used in SNMP exchanges, traps have their OID, bindings have their OIDs, … To help you manipulate those some functions are provided:

-- Attention, all these methods come from the git snmp-trap-default-functions.
-- It is recommended not to modify these files and to add similar functions with different behavior if necessary.
-- In case of edition, there will be need manually merge from snmp-trap-default-functions when upgrading to newest versions.

--- Method to fetch the last digit of a given oid
--@param oid The oid whose last digit is targeted
--@return The last digit of the given oid 
function helper_get_oid_last_digit(oid)
    local patternToFindDigitAfterLastDot = "%.%d+$"
    local lastDigitStart, lastDigitEnd = string.find(oid, patternToFindDigitAfterLastDot)
    return string.sub(oid, lastDigitStart+1, lastDigitEnd)
end

--- Method to fetch a list of sub identifiers out of an OID
--@param oid The OID to split into sub identifiers
--@return The list of sub identifiers extracted from the given OID
function helper_get_oid_sub_identifiers(oid)
    local subIdentifiers = {}
    for subIdentifier in (oid .. "."):gmatch("([^.]*).") do
        table.insert(subIdentifiers, subIdentifier)
    end
    return subIdentifiers
end

--- Method to fetch next to last sub identifier out of an OID (not the last digit, the one just before)
--@param oid the OID out of which the next to last sub identifier must be extracted
--@return The sub identifier just before the last one or nil if the oid has only one or less sub identifiers
function helper_get_oid_next_to_last_sub_identifier(oid)
    local subIdentifiers = helper_get_oid_sub_identifiers(oid)
    local nbSubIdentifiers = helper_get_table_length(subIdentifiers)
    if nbSubIdentifiers <= 1 then
        return nil
    end
    return subIdentifiers[nbSubIdentifiers-1]
end

--- Method to compute an OID out of a list of sub identifiers
--@param subIentifiers The list of sub identifiers to use to create the expected OID
--@return The OID constructed out of the provided list of sub identifiers
function helper_create_oid_from_sub_identifiers(subIdentifiers)
    local oid
    local currentIdentifier = 0
    local numberOfIdentifiers = helper_get_table_length(subIdentifiers)
    for index, subIdentifier in pairs(subIdentifiers) do
        currentIdentifier = currentIdentifier + 1
        if currentIdentifier == 1 then
            oid = subIdentifier
        else
            oid = oid .. "." .. subIdentifier
        end
    end
    return oid
end
Variables types manipulation

Whether it is trap and alarm attributes or custom variables you created, you will have to handle types for various reasons (e.g for a comparison to make sens it must take into account types). To help you managing those various types, some functions are provided :

-- Attention, all these methods come from the git snmp-trap-default-functions.
-- It is recommended not to modify these files and to add similar functions with different behavior if necessary.
-- In case of edition, there will be need manually merge from snmp-trap-default-functions when upgrading to newest versions.

--- Method to safely change the type of a variable
--@param variable The variable of which the type must be changed
--@param desired_type The type into which the method will change the given variable 
--@return The variable transformed into the given type if the change of type made sens, otherwise an error message
function helper_check_and_change_type(variable, desired_type)
    if type(variable) == "nil" then
        
    elseif type(variable) == "string" then
        if desired_type == "string" then
            return variable
        elseif desired_type == "number" then
            return tonumber(variable)
        end
    elseif type(variable) == "number" then
        if desired_type == "string" then
            return tostring(math.floor(variable))
        elseif desired_type == "number" then
            return variable
        end
    elseif type(variable) == "boolean" then
        if desired_type == "boolean" then
            return variable
        end
    elseif type(variable) == "function" then
        
    elseif type(variable) == "userdata" then
    
    elseif type(variable) == "thread" then
    
    elseif type(variable) == "table" then
        
    else
    
    end
  return "not set"
end
Table manipulation

Table can be useful in a lot of situation. To help you manipulate them some functions are provided :

-- Attention, all these methods come from the git snmp-trap-default-functions.
-- It is recommended not to modify these files and to add similar functions with different behavior if necessary.
-- In case of edition, there will be need manually merge from snmp-trap-default-functions when upgrading to newest versions.

--- Method to get the number of elements in a table
--@param table The table of which the method returns the number of elements
--@return The number of elements in the given table
function helper_get_table_length(table)
    local count = 0
    for _ in pairs(table) do
        count = count + 1
    end
    return count
end
Constants

A lot of default provided functions need common constants. To avoid repeating them each and every time they are needed (and possibly make some mistake while doing so) a constants file is provided:

-- Attention, all these methods come from the git snmp-trap-default-functions.
-- It is recommended not to modify these files and to add similar functions with different behavior if necessary.
-- In case of edition, there will be need manually merge from snmp-trap-default-functions when upgrading to newest versions.

STANDARD_TRAPS_OID_START = "1.3.6.1.6.3.1.1.5"
OID_TRAP_ENTERPRISE = "1.3.6.1.6.3.1.1.4.3"
OID_TRAP_ENTERPRISE_ZERO = OID_TRAP_ENTERPRISE .. ".0"

--Type
TYPE_STRING = "string"
TYPE_NUMBER = "number"
TYPE_BOOLEAN = "boolean"

TYPE_STRING_DEFAULT_VAL = ""
TYPE_NUMBER_DEFAULT_VAL = 0
TYPE_BOOLEAN_DEFAULT_VAL = false
Additional helpers functions

A few other functions are directly injected in the context (i.e available without having to register any file as resource).

Among other things, lookup helper functions are provided. Lookups are very useful to search information. OnSphere osp-snmp-trap lookup mechanism allows to search for a key in semi-colon CSV files.

Those CSV files must be registered as resources so that you can then use them through your Lua rules.

Note

When called, lookup functions do not return the key.

--- Print the message with all the fields with the given log level. Be warned that the log level is filtered if he's below the docker log level.
--@param logLevelInput The log level input ("TRACE", "DEBUG", "INFO", "WARN", "ERROR"), if no value is provided use INFO
--@param message the message to display
--@return nothing
function log(logLevelInput, message)
    -- DO NOT CHANGE or OVERRIDE THIS METHOD IT'S ONLY HERE TO PROVIDED AUTO-COMPLEXION.
end

--- Search from a lookup file with the lookup_table_name the entry with the key entry (first column)
--@param lookup_table_name The name of the lookup file
--@param element_key The key located in the first column of the CSV
--@return the value (string) or nil
function lookup(lookup_table_name, element_key)
    -- DO NOT CHANGE or OVERRIDE THIS METHOD IT'S ONLY HERE TO PROVIDED AUTO-COMPLEXION.
end

--- Search from a lookup file with the lookup_table_name the entry with the key entry (first column)
--@param lookup_table_name The name of the lookup file
--@param element_key The key located in the first column of the CSV
--@param default_array The default values as an array ex: {"key", "column2", "column3"}
--@return the value (string) or the default array
function lookup(lookup_table_name, element_key, default_array)
    -- DO NOT CHANGE or OVERRIDE THIS METHOD IT'S ONLY HERE TO PROVIDED AUTO-COMPLEXION.
end

--- Search from a lookup file with the lookup_table_name the entry with the key entry (first column)
--@param lookup_table_name The name of the lookup file
--@param element_key The key located in the first column of the CSV
--@param field_index The column selector
--@return the value or nil if the index doesn't exist
function lookup(lookup_table_name, element_key, field_index)
    -- DO NOT CHANGE or OVERRIDE THIS METHOD IT'S ONLY HERE TO PROVIDED AUTO-COMPLEXION.
end

--- Search from a lookup file with the lookup_table_name the entry with the key entry (first column)
--@param lookup_table_name The name of the lookup file
--@param element_key The key located in the first column of the CSV
--@param field_index The column selector
--@param default_array The default value
--@return the value or the default value
function lookup(lookup_table_name, element_key, field_index, default_value)
    -- DO NOT CHANGE or OVERRIDE THIS METHOD IT'S ONLY HERE TO PROVIDED AUTO-COMPLEXION.
end


--- Convert string to utf-8 from a given type
--@param input The text to convert
--@param source_encoding The type of encoding accepted values are : 
-- 37, 500, 500V1, 850, 851, 852, 855, 856, 857, 858, 860, 861, 862, 863, 864,
--  865, 866, 866NAV, 869, 874, 904, 1026, 1046, 1047, 8859_1, 8859_2, 8859_3,
-- 8859_4, 8859_5, 8859_6, 8859_7, 8859_8, 8859_9, 10646-1:1993,
-- 10646-1:1993/UCS4, ANSI_X3.4-1968, ANSI_X3.4-1986, ANSI_X3.4,
-- ANSI_X3.110-1983, ANSI_X3.110, ARABIC, ARABIC7, ARMSCII-8, ARMSCII8, ASCII,
-- ASMO-708, ASMO_449, BALTIC, BIG-5, BIG-FIVE, BIG5-HKSCS, BIG5, BIG5HKSCS,
-- BIGFIVE, BRF, BS_4730, CA, CN-BIG5, CN-GB, CN, CP-AR, CP-GR, CP-HU, CP037,
-- CP038, CP273, CP274, CP275, CP278, CP280, CP281, CP282, CP284, CP285, CP290,
-- CP297, CP367, CP420, CP423, CP424, CP437, CP500, CP737, CP770, CP771, CP772,
-- CP773, CP774, CP775, CP803, CP813, CP819, CP850, CP851, CP852, CP855, CP856,
-- CP857, CP858, CP860, CP861, CP862, CP863, CP864, CP865, CP866, CP866NAV,
-- CP868, CP869, CP870, CP871, CP874, CP875, CP880, CP891, CP901, CP902, CP903,
-- CP904, CP905, CP912, CP915, CP916, CP918, CP920, CP921, CP922, CP930, CP932,
-- CP933, CP935, CP936, CP937, CP939, CP949, CP950, CP1004, CP1008, CP1025,
-- CP1026, CP1046, CP1047, CP1070, CP1079, CP1081, CP1084, CP1089, CP1097,
-- CP1112, CP1122, CP1123, CP1124, CP1125, CP1129, CP1130, CP1132, CP1133,
-- CP1137, CP1140, CP1141, CP1142, CP1143, CP1144, CP1145, CP1146, CP1147,
-- CP1148, CP1149, CP1153, CP1154, CP1155, CP1156, CP1157, CP1158, CP1160,
-- CP1161, CP1162, CP1163, CP1164, CP1166, CP1167, CP1250, CP1251, CP1252,
-- CP1253, CP1254, CP1255, CP1256, CP1257, CP1258, CP1282, CP1361, CP1364,
-- CP1371, CP1388, CP1390, CP1399, CP4517, CP4899, CP4909, CP4971, CP5347,
-- CP9030, CP9066, CP9448, CP10007, CP12712, CP16804, CPIBM861, CSA7-1, CSA7-2,
-- CSASCII, CSA_T500-1983, CSA_T500, CSA_Z243.4-1985-1, CSA_Z243.4-1985-2,
-- CSA_Z243.419851, CSA_Z243.419852, CSDECMCS, CSEBCDICATDE, CSEBCDICATDEA,
-- CSEBCDICCAFR, CSEBCDICDKNO, CSEBCDICDKNOA, CSEBCDICES, CSEBCDICESA,
-- CSEBCDICESS, CSEBCDICFISE, CSEBCDICFISEA, CSEBCDICFR, CSEBCDICIT, CSEBCDICPT,
-- CSEBCDICUK, CSEBCDICUS, CSEUCKR, CSEUCPKDFMTJAPANESE, CSGB2312, CSHPROMAN8,
-- CSIBM037, CSIBM038, CSIBM273, CSIBM274, CSIBM275, CSIBM277, CSIBM278,
-- CSIBM280, CSIBM281, CSIBM284, CSIBM285, CSIBM290, CSIBM297, CSIBM420,
-- CSIBM423, CSIBM424, CSIBM500, CSIBM803, CSIBM851, CSIBM855, CSIBM856,
-- CSIBM857, CSIBM860, CSIBM863, CSIBM864, CSIBM865, CSIBM866, CSIBM868,
-- CSIBM869, CSIBM870, CSIBM871, CSIBM880, CSIBM891, CSIBM901, CSIBM902,
-- CSIBM903, CSIBM904, CSIBM905, CSIBM918, CSIBM921, CSIBM922, CSIBM930,
-- CSIBM932, CSIBM933, CSIBM935, CSIBM937, CSIBM939, CSIBM943, CSIBM1008,
-- CSIBM1025, CSIBM1026, CSIBM1097, CSIBM1112, CSIBM1122, CSIBM1123, CSIBM1124,
-- CSIBM1129, CSIBM1130, CSIBM1132, CSIBM1133, CSIBM1137, CSIBM1140, CSIBM1141,
-- CSIBM1142, CSIBM1143, CSIBM1144, CSIBM1145, CSIBM1146, CSIBM1147, CSIBM1148,
-- CSIBM1149, CSIBM1153, CSIBM1154, CSIBM1155, CSIBM1156, CSIBM1157, CSIBM1158,
-- CSIBM1160, CSIBM1161, CSIBM1163, CSIBM1164, CSIBM1166, CSIBM1167, CSIBM1364,
-- CSIBM1371, CSIBM1388, CSIBM1390, CSIBM1399, CSIBM4517, CSIBM4899, CSIBM4909,
-- CSIBM4971, CSIBM5347, CSIBM9030, CSIBM9066, CSIBM9448, CSIBM12712,
-- CSIBM16804, CSIBM11621162, CSISO4UNITEDKINGDOM, CSISO10SWEDISH,
-- CSISO11SWEDISHFORNAMES, CSISO14JISC6220RO, CSISO15ITALIAN, CSISO16PORTUGESE,
-- CSISO17SPANISH, CSISO18GREEK7OLD, CSISO19LATINGREEK, CSISO21GERMAN,
-- CSISO25FRENCH, CSISO27LATINGREEK1, CSISO49INIS, CSISO50INIS8,
-- CSISO51INISCYRILLIC, CSISO58GB1988, CSISO60DANISHNORWEGIAN,
-- CSISO60NORWEGIAN1, CSISO61NORWEGIAN2, CSISO69FRENCH, CSISO84PORTUGUESE2,
-- CSISO85SPANISH2, CSISO86HUNGARIAN, CSISO88GREEK7, CSISO89ASMO449, CSISO90,
-- CSISO92JISC62991984B, CSISO99NAPLPS, CSISO103T618BIT, CSISO111ECMACYRILLIC,
-- CSISO121CANADIAN1, CSISO122CANADIAN2, CSISO139CSN369103, CSISO141JUSIB1002,
-- CSISO143IECP271, CSISO150, CSISO150GREEKCCITT, CSISO151CUBA,
-- CSISO153GOST1976874, CSISO646DANISH, CSISO2022CN, CSISO2022JP, CSISO2022JP2,
-- CSISO2022KR, CSISO2033, CSISO5427CYRILLIC, CSISO5427CYRILLIC1981,
-- CSISO5428GREEK, CSISO10367BOX, CSISOLATIN1, CSISOLATIN2, CSISOLATIN3,
-- CSISOLATIN4, CSISOLATIN5, CSISOLATIN6, CSISOLATINARABIC, CSISOLATINCYRILLIC,
-- CSISOLATINGREEK, CSISOLATINHEBREW, CSKOI8R, CSKSC5636, CSMACINTOSH,
-- CSNATSDANO, CSNATSSEFI, CSN_369103, CSPC8CODEPAGE437, CSPC775BALTIC,
-- CSPC850MULTILINGUAL, CSPC858MULTILINGUAL, CSPC862LATINHEBREW, CSPCP852,
-- CSSHIFTJIS, CSUCS4, CSUNICODE, CSWINDOWS31J, CUBA, CWI-2, CWI, CYRILLIC, DE,
-- DEC-MCS, DEC, DECMCS, DIN_66003, DK, DS2089, DS_2089, E13B, EBCDIC-AT-DE-A,
-- EBCDIC-AT-DE, EBCDIC-BE, EBCDIC-BR, EBCDIC-CA-FR, EBCDIC-CP-AR1,
-- EBCDIC-CP-AR2, EBCDIC-CP-BE, EBCDIC-CP-CA, EBCDIC-CP-CH, EBCDIC-CP-DK,
-- EBCDIC-CP-ES, EBCDIC-CP-FI, EBCDIC-CP-FR, EBCDIC-CP-GB, EBCDIC-CP-GR,
-- EBCDIC-CP-HE, EBCDIC-CP-IS, EBCDIC-CP-IT, EBCDIC-CP-NL, EBCDIC-CP-NO,
-- EBCDIC-CP-ROECE, EBCDIC-CP-SE, EBCDIC-CP-TR, EBCDIC-CP-US, EBCDIC-CP-WT,
-- EBCDIC-CP-YU, EBCDIC-CYRILLIC, EBCDIC-DK-NO-A, EBCDIC-DK-NO, EBCDIC-ES-A,
-- EBCDIC-ES-S, EBCDIC-ES, EBCDIC-FI-SE-A, EBCDIC-FI-SE, EBCDIC-FR,
-- EBCDIC-GREEK, EBCDIC-INT, EBCDIC-INT1, EBCDIC-IS-FRISS, EBCDIC-IT,
-- EBCDIC-JP-E, EBCDIC-JP-KANA, EBCDIC-PT, EBCDIC-UK, EBCDIC-US, EBCDICATDE,
-- EBCDICATDEA, EBCDICCAFR, EBCDICDKNO, EBCDICDKNOA, EBCDICES, EBCDICESA,
-- EBCDICESS, EBCDICFISE, EBCDICFISEA, EBCDICFR, EBCDICISFRISS, EBCDICIT,
-- EBCDICPT, EBCDICUK, EBCDICUS, ECMA-114, ECMA-118, ECMA-128, ECMA-CYRILLIC,
-- ECMACYRILLIC, ELOT_928, ES, ES2, EUC-CN, EUC-JISX0213, EUC-JP-MS, EUC-JP,
-- EUC-KR, EUC-TW, EUCCN, EUCJP-MS, EUCJP-OPEN, EUCJP-WIN, EUCJP, EUCKR, EUCTW,
-- FI, FR, GB, GB2312, GB13000, GB18030, GBK, GB_1988-80, GB_198880,
-- GEORGIAN-ACADEMY, GEORGIAN-PS, GOST_19768-74, GOST_19768, GOST_1976874,
-- GREEK-CCITT, GREEK, GREEK7-OLD, GREEK7, GREEK7OLD, GREEK8, GREEKCCITT,
-- HEBREW, HP-GREEK8, HP-ROMAN8, HP-ROMAN9, HP-THAI8, HP-TURKISH8, HPGREEK8,
-- HPROMAN8, HPROMAN9, HPTHAI8, HPTURKISH8, HU, IBM-803, IBM-856, IBM-901,
-- IBM-902, IBM-921, IBM-922, IBM-930, IBM-932, IBM-933, IBM-935, IBM-937,
-- IBM-939, IBM-943, IBM-1008, IBM-1025, IBM-1046, IBM-1047, IBM-1097, IBM-1112,
-- IBM-1122, IBM-1123, IBM-1124, IBM-1129, IBM-1130, IBM-1132, IBM-1133,
-- IBM-1137, IBM-1140, IBM-1141, IBM-1142, IBM-1143, IBM-1144, IBM-1145,
-- IBM-1146, IBM-1147, IBM-1148, IBM-1149, IBM-1153, IBM-1154, IBM-1155,
-- IBM-1156, IBM-1157, IBM-1158, IBM-1160, IBM-1161, IBM-1162, IBM-1163,
-- IBM-1164, IBM-1166, IBM-1167, IBM-1364, IBM-1371, IBM-1388, IBM-1390,
-- IBM-1399, IBM-4517, IBM-4899, IBM-4909, IBM-4971, IBM-5347, IBM-9030,
-- IBM-9066, IBM-9448, IBM-12712, IBM-16804, IBM037, IBM038, IBM256, IBM273,
-- IBM274, IBM275, IBM277, IBM278, IBM280, IBM281, IBM284, IBM285, IBM290,
-- IBM297, IBM367, IBM420, IBM423, IBM424, IBM437, IBM500, IBM775, IBM803,
-- IBM813, IBM819, IBM848, IBM850, IBM851, IBM852, IBM855, IBM856, IBM857,
-- IBM858, IBM860, IBM861, IBM862, IBM863, IBM864, IBM865, IBM866, IBM866NAV,
-- IBM868, IBM869, IBM870, IBM871, IBM874, IBM875, IBM880, IBM891, IBM901,
-- IBM902, IBM903, IBM904, IBM905, IBM912, IBM915, IBM916, IBM918, IBM920,
-- IBM921, IBM922, IBM930, IBM932, IBM933, IBM935, IBM937, IBM939, IBM943,
-- IBM1004, IBM1008, IBM1025, IBM1026, IBM1046, IBM1047, IBM1089, IBM1097,
-- IBM1112, IBM1122, IBM1123, IBM1124, IBM1129, IBM1130, IBM1132, IBM1133,
-- IBM1137, IBM1140, IBM1141, IBM1142, IBM1143, IBM1144, IBM1145, IBM1146,
-- IBM1147, IBM1148, IBM1149, IBM1153, IBM1154, IBM1155, IBM1156, IBM1157,
-- IBM1158, IBM1160, IBM1161, IBM1162, IBM1163, IBM1164, IBM1166, IBM1167,
-- IBM1364, IBM1371, IBM1388, IBM1390, IBM1399, IBM4517, IBM4899, IBM4909,
-- IBM4971, IBM5347, IBM9030, IBM9066, IBM9448, IBM12712, IBM16804, IEC_P27-1,
-- IEC_P271, INIS-8, INIS-CYRILLIC, INIS, INIS8, INISCYRILLIC, ISIRI-3342,
-- ISIRI3342, ISO-2022-CN-EXT, ISO-2022-CN, ISO-2022-JP-2, ISO-2022-JP-3,
-- ISO-2022-JP, ISO-2022-KR, ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4,
-- ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, ISO-8859-9E,
-- ISO-8859-10, ISO-8859-11, ISO-8859-13, ISO-8859-14, ISO-8859-15, ISO-8859-16,
-- ISO-10646, ISO-10646/UCS2, ISO-10646/UCS4, ISO-10646/UTF-8, ISO-10646/UTF8,
-- ISO-CELTIC, ISO-IR-4, ISO-IR-6, ISO-IR-8-1, ISO-IR-9-1, ISO-IR-10, ISO-IR-11,
-- ISO-IR-14, ISO-IR-15, ISO-IR-16, ISO-IR-17, ISO-IR-18, ISO-IR-19, ISO-IR-21,
-- ISO-IR-25, ISO-IR-27, ISO-IR-37, ISO-IR-49, ISO-IR-50, ISO-IR-51, ISO-IR-54,
-- ISO-IR-55, ISO-IR-57, ISO-IR-60, ISO-IR-61, ISO-IR-69, ISO-IR-84, ISO-IR-85,
-- ISO-IR-86, ISO-IR-88, ISO-IR-89, ISO-IR-90, ISO-IR-92, ISO-IR-98, ISO-IR-99,
-- ISO-IR-100, ISO-IR-101, ISO-IR-103, ISO-IR-109, ISO-IR-110, ISO-IR-111,
-- ISO-IR-121, ISO-IR-122, ISO-IR-126, ISO-IR-127, ISO-IR-138, ISO-IR-139,
-- ISO-IR-141, ISO-IR-143, ISO-IR-144, ISO-IR-148, ISO-IR-150, ISO-IR-151,
-- ISO-IR-153, ISO-IR-155, ISO-IR-156, ISO-IR-157, ISO-IR-166, ISO-IR-179,
-- ISO-IR-193, ISO-IR-197, ISO-IR-199, ISO-IR-203, ISO-IR-209, ISO-IR-226,
-- ISO/TR_11548-1, ISO646-CA, ISO646-CA2, ISO646-CN, ISO646-CU, ISO646-DE,
-- ISO646-DK, ISO646-ES, ISO646-ES2, ISO646-FI, ISO646-FR, ISO646-FR1,
-- ISO646-GB, ISO646-HU, ISO646-IT, ISO646-JP-OCR-B, ISO646-JP, ISO646-KR,
-- ISO646-NO, ISO646-NO2, ISO646-PT, ISO646-PT2, ISO646-SE, ISO646-SE2,
-- ISO646-US, ISO646-YU, ISO2022CN, ISO2022CNEXT, ISO2022JP, ISO2022JP2,
-- ISO2022KR, ISO6937, ISO8859-1, ISO8859-2, ISO8859-3, ISO8859-4, ISO8859-5,
-- ISO8859-6, ISO8859-7, ISO8859-8, ISO8859-9, ISO8859-9E, ISO8859-10,
-- ISO8859-11, ISO8859-13, ISO8859-14, ISO8859-15, ISO8859-16, ISO11548-1,
-- ISO88591, ISO88592, ISO88593, ISO88594, ISO88595, ISO88596, ISO88597,
-- ISO88598, ISO88599, ISO88599E, ISO885910, ISO885911, ISO885913, ISO885914,
-- ISO885915, ISO885916, ISO_646.IRV:1991, ISO_2033-1983, ISO_2033,
-- ISO_5427-EXT, ISO_5427, ISO_5427:1981, ISO_5427EXT, ISO_5428, ISO_5428:1980,
-- ISO_6937-2, ISO_6937-2:1983, ISO_6937, ISO_6937:1992, ISO_8859-1,
-- ISO_8859-1:1987, ISO_8859-2, ISO_8859-2:1987, ISO_8859-3, ISO_8859-3:1988,
-- ISO_8859-4, ISO_8859-4:1988, ISO_8859-5, ISO_8859-5:1988, ISO_8859-6,
-- ISO_8859-6:1987, ISO_8859-7, ISO_8859-7:1987, ISO_8859-7:2003, ISO_8859-8,
-- ISO_8859-8:1988, ISO_8859-9, ISO_8859-9:1989, ISO_8859-9E, ISO_8859-10,
-- ISO_8859-10:1992, ISO_8859-14, ISO_8859-14:1998, ISO_8859-15,
-- ISO_8859-15:1998, ISO_8859-16, ISO_8859-16:2001, ISO_9036, ISO_10367-BOX,
-- ISO_10367BOX, ISO_11548-1, ISO_69372, IT, JIS_C6220-1969-RO,
-- JIS_C6229-1984-B, JIS_C62201969RO, JIS_C62291984B, JOHAB, JP-OCR-B, JP, JS,
-- JUS_I.B1.002, KOI-7, KOI-8, KOI8-R, KOI8-RU, KOI8-T, KOI8-U, KOI8, KOI8R,
-- KOI8U, KSC5636, L1, L2, L3, L4, L5, L6, L7, L8, L10, LATIN-9, LATIN-GREEK-1,
-- LATIN-GREEK, LATIN1, LATIN2, LATIN3, LATIN4, LATIN5, LATIN6, LATIN7, LATIN8,
-- LATIN9, LATIN10, LATINGREEK, LATINGREEK1, MAC-CENTRALEUROPE, MAC-CYRILLIC,
-- MAC-IS, MAC-SAMI, MAC-UK, MAC, MACCYRILLIC, MACINTOSH, MACIS, MACUK,
-- MACUKRAINIAN, MIK, MS-ANSI, MS-ARAB, MS-CYRL, MS-EE, MS-GREEK, MS-HEBR,
-- MS-MAC-CYRILLIC, MS-TURK, MS932, MS936, MSCP949, MSCP1361, MSMACCYRILLIC,
-- MSZ_7795.3, MS_KANJI, NAPLPS, NATS-DANO, NATS-SEFI, NATSDANO, NATSSEFI,
-- NC_NC0010, NC_NC00-10, NC_NC00-10:81, NF_Z_62-010, NF_Z_62-010_(1973),
-- NF_Z_62-010_1973, NF_Z_62010, NF_Z_62010_1973, NO, NO2, NS_4551-1, NS_4551-2,
-- NS_45511, NS_45512, OS2LATIN1, OSF00010001, OSF00010002, OSF00010003,
-- OSF00010004, OSF00010005, OSF00010006, OSF00010007, OSF00010008, OSF00010009,
-- OSF0001000A, OSF00010020, OSF00010100, OSF00010101, OSF00010102, OSF00010104,
-- OSF00010105, OSF00010106, OSF00030010, OSF0004000A, OSF0005000A, OSF05010001,
-- OSF100201A4, OSF100201A8, OSF100201B5, OSF100201F4, OSF100203B5, OSF1002011C,
-- OSF1002011D, OSF1002035D, OSF1002035E, OSF1002035F, OSF1002036B, OSF1002037B,
-- OSF10010001, OSF10010004, OSF10010006, OSF10020025, OSF10020111, OSF10020115,
-- OSF10020116, OSF10020118, OSF10020122, OSF10020129, OSF10020352, OSF10020354,
-- OSF10020357, OSF10020359, OSF10020360, OSF10020364, OSF10020365, OSF10020366,
-- OSF10020367, OSF10020370, OSF10020387, OSF10020388, OSF10020396, OSF10020402,
-- OSF10020417, PT, PT2, PT154, R8, R9, RK1048, ROMAN8, ROMAN9, RUSCII, SE, SE2,
-- SEN_850200_B, SEN_850200_C, SHIFT-JIS, SHIFTJISX0213, SHIFT_JIS,
-- SHIFT_JISX0213, SJIS-OPEN, SJIS-WIN, SJIS, SS636127, STRK1048-2002,
-- ST_SEV_358-88, T.61-8BIT, T.61, T.618BIT, TCVN-5712, TCVN, TCVN5712-1,
-- TCVN5712-1:1993, THAI8, TIS-620, TIS620-0, TIS620.2529-1, TIS620.2533-0,
-- TIS620, TS-5881, TSCII, TURKISH8, UCS-2, UCS-2BE, UCS-2LE, UCS-4, UCS-4BE,
-- UCS-4LE, UCS2, UCS4, UHC, UJIS, UK, UNICODE, UNICODEBIG, UNICODELITTLE,
-- US-ASCII, US, UTF-7, UTF-8, UTF-16, UTF-16BE, UTF-16LE, UTF-32, UTF-32BE,
-- UTF-32LE, UTF7, UTF8, UTF16, UTF16BE, UTF16LE, UTF32, UTF32BE, UTF32LE,
-- VISCII, WCHAR_T, WIN-SAMI-2, WINBALTRIM, WINDOWS-31J, WINDOWS-874,
-- WINDOWS-936, WINDOWS-1250, WINDOWS-1251, WINDOWS-1252, WINDOWS-1253,
-- WINDOWS-1254, WINDOWS-1255, WINDOWS-1256, WINDOWS-1257, WINDOWS-1258,
-- WINSAMI2, WS2, YU
-- -@return the value encoded
function convert_encoding(input, source_encoding)
    -- DO NOT CHANGE or OVERRIDE THIS METHOD IT'S ONLY HERE TO PROVIDED AUTO-COMPLEXION.
end
Default provided behavior

While serializing network traffic to replay it later can be very useful it is a very resource-intensive process (especially since every network packet received on configured port is serialized). It is very handy to replay whole scenario consisting of sequence of big quantity of SNMP messages, but way overkill when the idea in only to get a single message to be “re-processed” through Lua rules to find out why end result was not the one expected.

OnSphere offers a mechanism for you to easily replay an SNMP message. When you want to be able to replay an SNMP message, set the storeRawData parameter of the alarm you are enriching in the Lua rules.

Note

Note that this is automatically done when the processing of a rule fails (i.e script execution did not end properly)

The message will be stored exactly as it was received before processing it, as an array of bytes, in a special additional data field alarm.additionalData._rawData . Those raw data can then be sent back to the osp-snmp-trap module for replay by using any module that is able to send that request (e.g osp-scripts).

Warning

Storing the raw data of each SNMP message can severely affect database storage and performance. You should aim at keeping the sub-set of SNMP message whose raw data are kept to a minimum.

Flexibility

OnSphere provided scripting context offers a lot of flexibility letting you create any number of class and function you need. Additionally those user defined elements can be defined in separated files to ease browsing.

Alarm generation

The purpose of rules is to either discard the received message or generate an alarm. If no call to discard() function is reached before the end of rules processing, an alarm is published on the OnSphere communication bus for the osp-alarms module to deal with.

Note

You should always try to discard received message as soon as possible (when it has been decided received message has no reason to trigger an alarm) to avoid un-necessary processing.

SNMP v3

Version 3 of SNMP was designed (among other thing) in order to fix previous version’s weakness regarding security aspects which OnSphere osp-snmp-trap module handles though User Security Model (USM).

Version 3 of SNMP also added the notion of EngineId to uniquely identify an entity. While some managers will refuse a Trap coming from an agent whose EngineId is not registered, OnSphere osp-snmp-trap module will not. If filtering on EngineId is needed, it must be done in the Lua rules (you can look at this example for ideas on how to handle v3 messages depending on if they were authenticated and by witch USM).

Warning

Inform messages sent with an engineId different than the one configured for the osp-snmp-trap module will be dropped without being fed to the Lua rules.

Note

  • Authenticated messages are checked for timeliness

  • If an agent sends messages wil an “invalid” engine time, the osp-snmp-trap module can be restarted so that it restarts its internal count of the device engine time

PCAP replay tool

Requirement