---
name: "snmp_generic"
section: "3erl"
platform: "linux"
package: "erlang-manpages"
version: "1:25.2.3+dfsg-1+deb12u4"
release: "Debian 12 (Bookworm)"
platforms: ["linux"]
url: "https://new.carta.tech/snmp_generic"
---

# snmp\_generic(3erl)

Generic Functions for Implementing SNMP Objects in a Database

## NAME

snmp\_generic - Generic Functions for Implementing SNMP Objects in a Database

## DESCRIPTION

The module *snmp\_generic* contains generic functions for implementing tables (and variables) using the SNMP built-in database or Mnesia. These default functions are used if no instrumentation function is provided for a managed object in a MIB. Sometimes, it might be necessary to customize the behaviour of the default functions. For example, in some situations a trap should be sent if a row is deleted or modified, or some hardware is to be informed, when information is changed.

The overall structure is shown in the following figure:

```
         +---------------+
         |   SNMP Agent  |
         +- - - - - - - -+
         |      MIB      |
         +---------------+
                 |
         Association file       (associates a MIB object with
                 |               snmp_generic:table_funct
                 |               snmp_generic:variable_func)
+--------------------------------------+
|           snmp_generic               |  Support for get-next,
|                                      |  RowStatus operations
+----------------------+---------------+
|    snmpa_local_db    |    Mnesia     |  Database
+--------------+-------+---------------+
|     dets     |  ets  |
| (persistent) |       |
+--------------+-------+
```

Each function takes the argument *NameDb*, which is a tuple *{Name, Db}*, to identify which database the functions should use. *Name* is the symbolic name of the managed object as defined in the MIB, and *Db* is either *volatile*, *persistent*, or *mnesia*. If it is *mnesia*, all variables are stored in the Mnesia table *snmp\_variables* which must be a table with two attributes (not a Mnesia SNMP table). The SNMP tables are stored in Mnesia tables with the same names as the SNMP tables. All functions assume that a Mnesia table exists with the correct name and attributes. It is the programmer's responsibility to ensure this. Specifically, if variables are stored in Mnesia, the table *snmp\_variables* must be created by the programmer. The record definition for this table is defined in the file *snmp/include/snmp\_types.hrl*.

If an instrumentation function in the association file for a variable *myVar* does not have a name when compiling an MIB, the compiler generates an entry.

```
{myVar, {snmp_generic, variable_func, [{myVar, Db]}}.
```

And for a table:

```
{myTable, {snmp_generic, table_func, [{myTable, Db]}}.
```

## DATA TYPES

In the functions defined below, the following types are used:

```
name_db() = {name(), db()}
name() = atom()
db() = volatile | persistent | mnesia
row_index() = [int()]
columns() = [column()] | [{column(), value()}]
column() = int()
value() = term()
```

- ***row\_index()*:**

  Denotes the last part of the OID which specifies the index of the row in the table (see RFC1212, 4.1.6 for more information about INDEX).

- ***columns()*:**

  Is a list of column numbers in the case of a *get* operation, and a list of column numbers and values in the case of a *set* operation.

## EXPORTS

**get\_status\_col(Name, Cols)**\
 **get\_status\_col(NameDb, Cols) -\> {ok, StatusVal} \| false**\

Types:

Name = name()\
 NameDb = name\_db()\
 Cols = columns()\
 StatusVal = term()\

Gets the value of the status column from *Cols*.

This function can be used in instrumentation functions for *is\_set\_ok*, *undo* or *set* to check if the status column of a table is modified.

**get\_index\_types(Name)**\

Types:

Name = name()\

Gets the index types of *Name*

This function can be used in instrumentation functions to retrieve the index types part of the table info.

**get\_table\_info(Name, Item) -\> table\_info\_result()**\

Types:

Name = name()\
 Item = table\_item() \| all\
 table\_item() = nbr\_of\_cols \| defvals \| status\_col \| not\_accessible \| index\_types \| first\_accessible \| first\_own\_index\
 table\_info\_result() = Value \| \[{table\_item(), Value}\]\
 Value = term()\

Get a specific table info item or, if *Item* has the value *all*, a two tuple list (property list) is instead returned with all the items and their respctive values of the given table.

This function can be used in instrumentation functions to retrieve a given part of the table info.

**table\_func(Op1, NameDb)**\
 **table\_func(Op2, RowIndex, Cols, NameDb) -\> Ret**\

Types:

Op1 = new \| delete \
 Op2 = get \| next \| is\_set\_ok \| set \| undo\
 NameDb = name\_db()\
 RowIndex = row\_index()\
 Cols = columns()\
 Ret = term()\

This is the default instrumentation function for tables.

- \*

  The *new* function creates the table if it does not exist, but only if the database is the SNMP internal db.

- \*

  The *delete* function does not delete the table from the database since unloading an MIB does not necessarily mean that the table should be destroyed.

- \*

  The *is\_set\_ok* function checks that a row which is to be modified or deleted exists, and that a row which is to be created does not exist.

- \*

  The *undo* function does nothing.

- \*

  The *set* function checks if it has enough information to make the row change its status from *notReady* to *notInService* (when a row has been been set to *createAndWait*). If a row is set to *createAndWait*, columns without a value are set to *noinit*. If Mnesia is used, the set functionality is handled within a transaction.

If it is possible for a manager to create or delete rows in the table, there must be a *RowStatus* column for *is\_set\_ok*, *set* and *undo* to work properly.

The function returns according to the specification of an instrumentation function.

**table\_get\_elements(NameDb, RowIndex, Cols) -\> Values**\

Types:

NameDb = name\_db()\
 RowIndex = row\_index()\
 Cols = columns()\
 Values = \[value() \| noinit\]\

Returns a list with values for all columns in *Cols*. If a column is undefined, its value is *noinit*.

**table\_next(NameDb, RestOid) -\> RowIndex \| endOfTable**\

Types:

NameDb = name\_db()\
 RestOid = \[int()\]\
 RowIndex = row\_index()\

Finds the indices of the next row in the table. *RestOid* does not have to specify an existing row.

**table\_row\_exists(NameDb, RowIndex) -\> bool()**\

Types:

NameDb = name\_db()\
 RowIndex = row\_index()\

Checks if a row in a table exists.

**table\_set\_elements(NameDb, RowIndex, Cols) -\> bool()**\

Types:

NameDb = name\_db()\
 RowIndex = row\_index()\
 Cols = columns()\

Sets the elements in *Cols* to the row specified by *RowIndex*. No checks are performed on the new values.

If the Mnesia database is used, this function calls *mnesia:write* to store the values. This means that this function must be called from within a transaction (*mnesia:transaction/1* or *mnesia:dirty/1*).

**variable\_func(Op1, NameDb)**\
 **variable\_func(Op2, Val, NameDb) -\> Ret**\

Types:

Op1 = new \| delete \| get\
 Op2 = is\_set\_ok \| set \| undo\
 NameDb = name\_db()\
 Val = value()\
 Ret = term()\

This is the default instrumentation function for variables.

The *new* function creates a new variable in the database with a default value as defined in the MIB, or a zero value (depending on the type).

The *delete* function does not delete the variable from the database.

The function returns according to the specification of an instrumentation function.

**variable\_get(NameDb) -\> {value, Value} \| undefined**\

Types:

NameDb = name\_db()\
 Value = value()\

Gets the value of a variable.

**variable\_set(NameDb, NewVal) -\> true \| false**\

Types:

NameDb = name\_db()\
 NewVal = value()\

Sets a new value to a variable. The variable is created if it does not exist. No checks are made on the type of the new value.

Returns *false* if the *NameDb* argument is incorrectly specified, otherwise *true*.

## EXAMPLE

The following example shows an implementation of a table which is stored in Mnesia, but with some checks performed at set-request operations.

```
myTable_func(new, NameDb) ->   % pass unchanged
  snmp_generic:table_func(new, NameDb).
myTable_func(delete, NameDb) ->   % pass unchanged
  snmp_generic:table_func(delete, NameDb).
%% change row
myTable_func(is_set_ok, RowIndex, Cols, NameDb) ->
  case snmp_generic:table_func(is_set_ok, RowIndex,
                               Cols, NameDb) of
    {noError, 0} ->
      myApplication:is_set_ok(RowIndex, Cols);
    Err ->
      Err
  end;
myTable_func(set, RowIndex, Cols, NameDb) ->
  case snmp_generic:table_func(set, RowIndex, Cols,
                               NameDb),
    {noError, 0} ->
      % Now the row is updated, tell the application
      myApplication:update(RowIndex, Cols);
    Err ->
      Err
  end;
myTable_func(Op, RowIndex, Cols, NameDb) ->   % pass unchanged
  snmp_generic:table_func(Op, RowIndex, Cols, NameDb).
```

The *.funcs* file would look like:

```
{myTable, {myModule, myTable_func, [{myTable, mnesia}]}}.
```
