# Traps Processing Functions

NetObserv SNMP Trap introduces a new DSL Processor which is responsible for processing and enriching the incoming traps. The DSL Processor is a powerful tool designed to streamline and enhance your data processing workflows. It allows you to define and execute complex data transformations using a simple and intuitive domain-specific language (DSL). The collector leverages Benthos Bloblang as a DSL and includes additional SNMP-specific functions to enrich and transform the data from SNMP traps.

## Features

* **Intuitive Syntax**: Write clear and concise transformation rules.
* **High Performance**: Optimized for speed and efficiency.
* **Flexibility**: Easily adaptable to various data processing needs.

## Custom Functions

The DSL processor supports the following custom functions:

### snmp\_display\_string()

The `snmp_display_string()` transforms a raw `OCTET STRING` to a `DisplayString` value (per `SNMPv2-TC`). In the case of an error while processing the raw value, an empty string is returned.

**Example**

```
root.out.netapp.productSerialNum = this.trap.VarBinds.index(1).Value.snmp_display_string()
```

### snmp\_date\_and\_time() <a href="#snmp_date_and_time" id="snmp_date_and_time"></a>

The `snmp_date_and_time()` transforms a raw `OCTET STRING` to a `DateAndTime` value (per `SNMPv2-TC`). In the case of an error processing the raw value an empty string is returned.

**Example**

```
root.out.juniper.jnxOperatingRestartTime = this.trap.VarBinds.index(0).Value.snmp_date_and_time().ts_unix_milli()
```

### snmp\_int\_enum\_enrich()

{% hint style="warning" %}
previously called `enum_enrich()`
{% endhint %}

The `snmp_int_enum_enrich()` function transforms an integer to the enumerated string that it represents. Integer enumerations are located by default in `/etc/elastiflow/snmp/enums/integer`. Note that `enum_enrich()` is deprecated. While it still works, it will be removed in a future release.

**Example**

```
root.out.IETF.ospfLsdbType = this.trap.VarBinds.index(2).Value.snmp_int_enum_enrich(".1.3.6.1.2.1.14.4.1.2")
```

**Syntax**

```
snmp_int_enum_enrich("[OID]")
```

**Parameters**

* `OID` (string): The Object Identifier used as a key for the enumeration keys.

### snmp\_int\_display\_hint()

The `snmp_int_display_hint()` function transforms a raw integer-based value to a display-able string.

Example:

```
root.out.ietf.l2tpTunnelConfigReassemblyTimeout = this.trap.VarBinds.index(0).Value.snmp_int_display_hint("d-3")
```

**Syntax**

```
snmp_int_display_hint("[RFC2579-compatible integer-based display hint]")
```

**Parameters**

* `RFC2579-compatible integer-based display hint` (string): The value of the `DISPLAY-HINT` specified for an integer-based MIB object. The display hint must be compatible with RFC 2579, section 3.1.

### snmp\_mac\_address() <a href="#snmp_mac_address" id="snmp_mac_address"></a>

The `snmp_mac_address()` function transforms a raw `OCTET STRING` to a `MacAddress` value (per `SNMPv2-TC`). In the case of an error processing the raw value an empty string is returned.

**Example**

```
root.out.cisco.cVpcSystemOperMacAddress = this.trap.VarBinds.index(2).Value.snmp_mac_address()
```

### snmp\_octet\_string() <a href="#snmp_octet_string" id="snmp_octet_string"></a>

The `snmp_octet_string()` function transforms a raw `OCTET STRING` to a hex string, e.g. `0708090a0b0c`. In the case of an error processing the raw value an empty string is returned.

**Example**

```
root.out.IETF.nlmLogVariableOpaqueVal = this.trap.VarBinds.index(0).Value.snmp_octet_string()
```

### snmp\_octet\_display\_hint()

The `snmp_octet_display_hint()` function transforms a raw value of type `OCTET STRING` to a display-able string.

Example:

```
root.out.juniper.jnxMplsLdpEntityLdpId = this.trap.VarBinds.index(0).Value.snmp_octet_display_hint("1d.1d.1d.1d:2d")
```

**Syntax**

```
snmp_octet_display_hint("[RFC2579-compatible octet-format display hint]")
```

**Parameters**

* `RFC2579-compatible octet-format display hint` (string): The value of the `DISPLAY-HINT` specified for an octet-format MIB object. The display hint must be compatible with RFC 2579, section 3.1.

### snmp\_oid\_get\_index() <a href="#snmp_oid_get_index" id="snmp_oid_get_index"></a>

The `snmp_oid_get_index()` function extracts the Index portion of a variable binding OID following a supplied prefix.

**Example**

```
root.out.object.index = this.trap.VarBinds.index(0).OID.snmp_oid_get_index(".1.3.6.1.2.1.14.4.1.2")
```

**Syntax**

```
snmp_oid_get_index("[OID]")
```

**Parameters**

* `OID` (string): The Object Identifier used as a key for the enumeration keys.

### snmp\_oid\_extract\_index() <a href="#snmp_oid_extract_index" id="snmp_oid_extract_index"></a>

The `snmp_oid_extract_index()` function extracts the index values from a variable binding OID based on a comma-separated list of index types. The output is an array of index values.

**Example**

```
root.out.object.index.snmp_oid_extract_index("IpAddress,Integer,IpAddress,IpAddress")
```

**Syntax**

```
snmp_oid_extract_index("[comma-separated list of Index value types]")
```

**Parameters**

* `comma-separated list of Index value types` (string): The list of index value types to extract from the OID index.

The following is a list of supported values. Note that these are the same index value types supported by the NetObserv SNMP Collector object definitions.

* `Integer`
* `OctetString`
* `ImplicitOctetString`
* `ObjectIdentifier`
* `ImplicitObjectIdentifier`
* `Integer32`
* `IpAddress`
* `MacAddress`
* `Unsigned32`
* `Opaque`

### snmp\_inet\_address() <a href="#snmp_inet_address" id="snmp_inet_address"></a>

The `snmp_inet_address()` function transforms an `InetAddress` value (per `INET-ADDRESS-MIB`) into an IP address, IP address with Zone, or DNS name based on an `Integer` value of `InetAddressType`.

**Example**

```
root.out.TEST.inetAddress = this.trap.VarBinds.index(2).Value.snmp_inet_address(root.out.TEMP.inetAddressType)
```

**Syntax**

```
snmp_inet_address([InetAddressType])
```

**Parameters**

* `InetAddressType` (Integer): The value of `InetAddressType` which indicates the type of the `InetAddress` that is being transformed.

### snmp\_int\_to\_ipv4() <a href="#snmp_int_to_ipv4" id="snmp_int_to_ipv4"></a>

The `snmp_int_to_ipv4()` function transforms an Integer raw value into an IPv4 address string.

**Example**

```
root.out.TEST.intToIPv4 = this.trap.VarBinds.index(3).Value.snmp_int_to_ipv4()
```

## Examples

### Extract and transform index values from the OID of a variable binding <a href="#extract-and-transform-index-values-from-the-oid-of-a-variable-binding" id="extract-and-transform-index-values-from-the-oid-of-a-variable-binding"></a>

The following variable binding contains and instance of `ospfLsdbType` from `OSPF-MIB`.

```json
{
  Name:  ".1.3.6.1.2.1.14.4.1.2.0.0.0.103.3.155.172.64.15.192.168.215.36", // ospfLsdbType
  Type:  Integer,
  Value: 3,
}
```

First we extract the index portion of the variable bindings OID:

```
root.out.snmp.object.index = this.trap.VarBinds.index(0).OID.snmp_oid_get_index(".1.3.6.1.2.1.14.4.1.2")
```

Which produces the following output:

```json
{
    "snmp":
        "object": {
            "index": "0.0.0.103.3.155.172.64.15.192.168.215.36"
        }
    }
}
```

Next we extract the individual components of the index, assigning them to a temporary variable that can be deleted later.

```
root.TEMP.ospfLsdbEntry = root.out.object.index.snmp_oid_extract_index("IpAddress,Integer,IpAddress,IpAddress")
```

We can then assign the values from the array to fields in the output record. Note the use of `snmp_int_enum_enrich()` to also transform `root.out.ospf.LsdbType` to its enumerated string value.

```
root.out.ospf.LsdbAreaId = root.TEMP.ospfLsdbEntry.index(0)
root.out.ospf.LsdbType = root.TEMP.ospfLsdbEntry.index(1).snmp_int_enum_enrich(".1.3.6.1.2.1.14.4.1.2")
root.out.ospf.LsdbLsid = root.TEMP.ospfLsdbEntry.index(2)
root.out.ospf.LsdbRouterId = root.TEMP.ospfLsdbEntry.index(3)
```

The resulting output record is now:

```json
{
    "ospf": {
        "LsdbAreaId": "0.0.0.103",
        "LsdbLsid": "155.172.64.15",
        "LsdbRouterId": "192.168.215.36",
        "LsdbType": "summary link"
    },
    "snmp":
        "object": {
            "index": "0.0.0.103.3.155.172.64.15.192.168.215.36"
        }
    }
}
```

### Handling the various forms of IP addresses <a href="#handling-the-various-forms-of-ip-addresses" id="handling-the-various-forms-of-ip-addresses"></a>

SNMP has various ways of expressing IP addresses.

* Originally SNMP only supported IPv4 addresses, the `IpAddress` type.
* As an IPv4 address is 4 bytes in size, some vendors choose to use a 32-bit integer to express the four bytes.
* To add support for IPv6 and other possible types, the `INET-ADDRESS-MIB` introduced `InetAddress` and `InetAddressType`, where the latter declares the type, and thus the necessary transformation, of the former. As a result these two value are commonly seen together.

#### **Handling values of types `InetAddress` and `InetAddressType`**

Let's look at this last use-case first. Consider the following variable bindings which contain an `InetAddressType` and an `InetAddress`.

```json
{
  Name:  ".1.2.3.4.5.6.7.8.9.0.1", // IPv6 InetAddressType
  Type:  Integer,
  Value: 2,
},
{
  Name:  ".1.2.3.4.5.6.7.8.9.0.2", // IPv6 InetAddress
  Type:  OctetString,
  Value: []byte{0x20, 0x1, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34},
}
```

Let's first assign the `InetAddressType` to a field.

```
root.out.MyInetAddressType = this.trap.VarBinds.index(1).Value
```

We can then pass this `InetAddressType` value into `snmp_inet_address()` to transform the `InetAddress` variable binding's value.

```
root.out.MyInetAddress = this.trap.VarBinds.index(2).Value.snmp_inet_address(root.out.MyInetAddressType)
```

The resulting record fields are:

```json
{
    "MyInetAddress": "2001:db8:85a3::8a2e:370:7334",
    "MyInetAddressType": 2
}
```

Note that we could also use `snmp_int_enum_enrich()` to further transform `MyInetAddressType`, or we could drop the field if it is no longer needed after the transformation of `MyInetAddress`.

#### **Handling IPv4 addresses expressed as a 32-bit integer**

As mentioned above, an IPv4 address is 4 bytes in size, so some vendors will choose to use a 32-bit integer to express the four bytes of the address.

```json
{
  Name:  ".1.2.3.4.5.6.7.8.9.0.3", // 192.168.1.1 as an Unsigned32
  Type:  Uinteger32,
  Value: uint32(3232235777),
}
```

The `snmp_int_to_ipv4()` function allows the integer value to be easily transformed into an IPv4 address.

```
root.out.MyIntToIPv4 = this.trap.VarBinds.index(3).Value.snmp_int_to_ipv4()
```

The resulting output is:

```json
{
    "MyIntToIPv4": "192.168.1.1"
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.elastiflow.com/trapcoll/configuration/processing-traps/traps-processing-functions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
