# `snmpm_user` [🔗](https://github.com/kikofernandez/otp/blob/kiko/otp/release-gh-action-backup-continuation/OTP-20040/lib/snmp/src/manager/snmpm_user.erl#L23) Behaviour module for the SNMP manager user. This module defines the behaviour of the manager user. A `snmpm_user` compliant module must export the following functions: - `c:handle_error/3` - `c:handle_agent/5` - `c:handle_pdu/4` - `c:handle_trap/3` - `c:handle_inform/3` - `c:handle_report/3` - `c:handle_invalid_result/2` The semantics of them and their exact signatures are explained below. Some of the function has no defined return value (`void()`), they can of course return anything. But the functions that do have specified return value(s) _must_ adhere to this. None of the functions can use exit of throw to return. If the manager is not configured to use any particular transport domain, the behaviour `handle_agent/5` will for backwards copmpatibility reasons be called with the old `IpAddr` and `PortNumber` arguments # `ip_address` *not exported* ```elixir -type ip_address() :: inet:ip_address(). ``` # `port_number` *not exported* ```elixir -type port_number() :: inet:port_number(). ``` # `snmp_gen_info` ```elixir -type snmp_gen_info() :: {ErrorStatus :: atom(), ErrorIndex :: pos_integer(), Varbinds :: [snmp:varbind()]}. ``` General error information (does not _have_ to indicate an error).. # `snmp_v1_trap_info` ```elixir -type snmp_v1_trap_info() :: {Enteprise :: snmp:oid(), Generic :: integer(), Spec :: integer(), Timestamp :: integer(), Varbinds :: [snmp:varbind()]}. ``` Trap related information. # `handle_agent` ```elixir -callback handle_agent(Domain :: atom(), Address :: term(), Type :: pdu | trap | inform | report, SnmpInfo :: snmp_gen_info() | snmp_v1_trap_info(), UserData :: term()) -> Reply :: ignore | {register, UserId :: term(), RTargetName :: snmpm:target_name(), AgentConfig :: [snmpm:agent_config()]}. ``` This function is called when a message is received from an unknown agent. Note that this will always be the default user that is called. For more info about the `agent_config()`, see `snmpm:register_agent/3`. The arguments `Type` and `SnmpInfo` relates in the following way: - `pdu` \- `SnmpPduInfo` (see `c:handle_pdu/4` for more info). - `trap` \- `SnmpTrapInfo` (see `c:handle_trap/3` for more info). - `report` \- `SnmpReportInfo` (see `c:handle_report/3` for more info). - `inform` \- `SnmpInformInfo` (see `c:handle_inform/3` for more info). The only user which would return `{register, UserId, TargetName, AgentConfig}` is the _default user_. # `handle_error` ```elixir -callback handle_error(ReqId :: netif | integer(), Reason :: {unexpected_pdu, SnmpInfo :: snmp_gen_info()} | {invalid_sec_info, SecInfo :: term(), SnmpInfo :: snmp_gen_info()} | {failed_processing_message, {securityError, SecurityError :: atom(), Info :: proplists:proplist()}} | {empty_message, TransportDomain :: atom(), {Addr :: ip_address(), Port :: port_number()}} | term(), UserData :: term()) -> snmp:void(). ``` This function is called when the manager needs to communicate an "asynchronous" error to the user: e.g. failure to send an asynchronous message (i.e. encoding error), a received message was discarded due to security error, the manager failed to generate a response message to a received inform-request, or when receiving an unexpected PDU from an agent (could be an expired async request). If `ReqId` is less then 0, it means that this information was not available to the manager (that info was never retrieved before the message was discarded). For `SnmpInfo` see handle_agent below. When `Reason` is `{failed_processing_message, {securityError, SecurityError, Opts}}`, the `Opts` proplist may contain a `sec_data` entry with USM security parameters from the received message. In particular, when `SecurityError` is `usmStatsUnknownEngineIDs`, the `sec_data` proplist contains `msgAuthoritativeEngineID` and `msgUserName`, which can be used for SNMPv3 USM EngineID discovery (RFC 3414, Section 4). Note that there is a special case when the value of `ReqId` has the value of the atom `netif`. This means that the NetIF process has suffered a "fatal" error and been restarted. With possible loss of traffic\! # `handle_inform` ```elixir -callback handle_inform(TargetName :: snmpm:target_name(), SnmpInform :: snmp_gen_info(), UserData :: term()) -> Reply :: ignore | no_reply | unregister | {register, UserId :: term(), RTargetName :: snmpm:target_name(), AgentConfig :: [snmpm:agent_config()]}. ``` Handle a inform message. For more info about the `agent_config()`, see `snmpm:register_agent/3`. The only user which would return `{register, UserId, TargetName2, AgentConfig}` is the _default user_. If the [inform request behaviour](snmp_config.md#manager_irb) configuration option is set to `user` or `{user, integer()}`, the response (acknowledgment) to this inform-request will be sent when this function returns. # `handle_invalid_result` *since OTP R16B03* *optional* ```elixir -callback handle_invalid_result(In, Out) -> no_return() when In :: {Fun :: atom(), Args :: list()}, Out :: {crash, CrashInfo} | {result, InvalidResult :: term()}, CrashInfo :: {ErrorType :: atom(), Error :: term(), Stacktrace :: erlang:stacktrace()}. ``` If _any_ of the _other_ callback functions crashes (exit, throw or a plain crash) or return an invalid result (if a valid return has been specified), this function is called. The purpose is to allow the user handle this error (for instance to issue an error report). `IN` reprecents the function called (and its arguments). `OUT` represents the unexpected/invalid result. # `handle_pdu` ```elixir -callback handle_pdu(TargetName :: snmpm:target_name(), ReqId :: term(), SnmpResponse :: snmp_gen_info(), UserData :: term()) -> snmp:void(). ``` Handle the reply to an asynchronous request, such as [async_get](`snmpm:async_get2/4`), [async_get_next](`snmpm:async_get_next2/4`) or [async_set](`snmpm:async_set2/4`). It could also be a late reply to a synchronous request. `ReqId` is returned by the asynchronous request function. # `handle_report` ```elixir -callback handle_report(TargetName :: snmpm:target_name(), SnmpReport :: snmp_gen_info(), UserData :: term()) -> Reply :: ignore | unregister | {register, UserId :: term(), RTargetName :: snmpm:target_name(), AgentConfig :: [snmpm:agent_config()]}. ``` Handle a report message. For more info about the `agent_config()`, see `snmpm:register_agent/3`. The only user which would return `{register, UserId, TargetName2, AgentConfig}` is the _default user_. # `handle_trap` ```elixir -callback handle_trap(TargetName :: snmpm:target_name(), SnmpTrapInfo :: snmp_gen_info() | snmp_v1_trap_info(), UserData :: term()) -> Reply :: ignore | unregister | {register, UserId :: term(), RTargetName :: snmpm:target_name(), AgentConfig :: [snmpm:agent_config()]}. ``` Handle a trap/notification message from an agent. For more info about the `agent_config()`, see `snmpm:register_agent/3`. The only user which would return `{register, UserId, TargetName2, agent_info()}` is the _default user_. --- *Consult [api-reference.md](api-reference.md) for complete listing*