snmpm(3erl)

πŸ“¦
version 25.3.2.8 Β· 4 versions
, in ubuntu noble

πŸ’– NAME πŸ’–

Okay bestie, this is snmpm β€” the Erlang manual page snmpm(3erl) β€” and it's literally the interface functions to the SNMP toolkit manager. main character energy, no cap. πŸ’…

🌸 DESCRIPTION 🌸

The module snmpm contains interface functions to the SNMP manager. That's the whole vibe check for this section. 🫢

πŸŽ€ COMMON DATA TYPES πŸŽ€

These are the shared types used in the functions below β€” don't skip them, they show up everywhere:

oid() = [byte()]  -  The oid() type is used to represent an ASN.1 OBJECT IDENTIFIER
snmp_reply() = {error_status(), error_index(), varbinds()}
error_status() = noError | atom()
error_index() = integer()
varbinds() = [varbind()]
atl_type() = read | write | read_write
target_name() = string()  -  Is a unique *non-empty* string
vars_and_vals() = [var_and_val()]
var_and_val() = {oid(), value_type(), value()} | {oid(), value()}
value_type() = o ('OBJECT IDENTIFIER') |
               i ('INTEGER') |
               u ('Unsigned32') |
               g ('Unsigned32') |
               s ('OCTET SRING') |
               b ('BITS') |
               ip ('IpAddress') |
               op ('Opaque') |
               c32 ('Counter32') |
               c64 ('Counter64') |
               tt ('TimeTicks')
value() = term()
community() = string()
sec_model() = any | v1 | v2c | usm
sec_name() = string()
sec_level() = noAuthNoPriv | authNoPriv | authPriv

See also the data types in snmpa_conf.


✨ EXPORTS ✨

πŸ’« monitor() -> Ref

Types:

Ref = reference()

Monitor the SNMP manager. In case of a crash, the calling (monitoring) process will get a 'DOWN' message (see the erlang module for more info). obsessed with a good crash notification, honestly.

πŸ’« demonitor(Ref) -> void()

Types:

Ref = reference()

Turn off monitoring of the SNMP manager. bye-bye monitor, we hardly knew ye. πŸ¦‹

πŸ’« notify_started(Timeout) -> Pid

Types:

Timeout = integer()
Pid = pid()

Request a notification (message) when the SNMP manager has started. πŸŽ€

The Timeout is the time the request is valid. The value has to be greater then zero.

The Pid is the process handling the supervision of the SNMP manager start. When the manager has started a completion message will be sent to the client from this process: {snmpm_started, Pid}. If the SNMP manager was not started in time, a timeout message will be sent to the client: {snmpm_start_timeout, Pid}.

A client application that is dependent on the SNMP manager will use this function in order to be notified of when the manager has started. There are two situations when this is useful:

  • During the start of a system, when a client application could start prior to the SNMP manager but is dependent upon it, and therefore has to wait for it to start.
  • When the SNMP manager has crashed, the dependent client application has to wait for the SNMP manager to be restarted before it can reconnect.

The function returns the pid() of a handler process, that does the supervision on behalf of the client application. Note that the client application is linked to this handler.

This function is used in conjunction with the monitor function. linked handler bestie behavior fr fr. 🫢

πŸ’« cancel_notify_started(Pid) -> void()

Types:

Pid = pid()

Cancel a previous request to be notified of SNMP manager start. not me canceling my own notifications πŸ’€.

πŸ’« register_user(Id, Module, Data) -> ok | {error, Reason}

πŸ’« register_user(Id, Module, Data, DefaultAgentConfig) -> ok | {error, Reason}

Types:

Id = term()
Module = snmpm_user()
Data = term()
DefaultAgentConfig = [default_agent_config()]
default_agent_config() = {Item, Val}
Item = community | timeout | max_message_size | version |
       sec_model | sec_name | sec_level
Val = term()
Reason = term()
snmpm_user() = Module implementing the snmpm_user behaviour

Register the manager entity (=user) responsible for specific agent(s).

Module is the callback module (snmpm_user behaviour) which will be called whenever something happens (detected agent, incoming reply or incoming trap/notification). Note that this could have already been done as a consequence of the node config. (see users.conf).

The argument DefaultAgentConfig is used as default values when this user register agents.

The type of Val depends on Item:

community = string()
timeout = integer() | snmp_timer()
max_message_size = integer()
version = v1 | v2 | v3
sec_model = any | v1 | v2c | usm
sec_name = string()
sec_level = noAuthNoPriv | authNoPriv | authPriv

user registration era ✨

πŸ’« register_user_monitor(Id, Module, Data) -> ok | {error, Reason}

πŸ’« register_user_monitor(Id, Module, Data, DefaultAgentConfig) -> ok | {error, Reason}

Types:

Id = term()
Module = snmpm_user()
DefaultAgentConfig = [default_agent_config()]
default_agent_config() = {Item, Val}
Item = community | timeout | max_message_size | version |
       sec_model | sec_name | sec_level
Val = term()
Data = term()
Reason = term()
snmpm_user() = Module implementing the snmpm_user behaviour

Register the monitored manager entity (=user) responsible for specific agent(s).

The process performing the registration will be monitored. Which means that if that process should die, all agents registered by that user process will be unregistered. All outstanding requests will be canceled. πŸ’€ harsh but fair, bestie.

Module is the callback module (snmpm_user behaviour) which will be called whenever something happens (detected agent, incoming reply or incoming trap/notification). Note that this could have already been done as a consequence of the node config. (see users.conf).

The argument DefaultAgentConfig is used as default values when this user register agents.

The type of Val depends on Item:

community = string()
timeout = integer() | snmp_timer()
max_message_size = integer()
version = v1 | v2 | v3
sec_model = any | v1 | v2c | usm
sec_name = string()
sec_level = noAuthNoPriv | authNoPriv | authPriv

πŸ’« unregister_user(Id) -> ok | {error, Reason}

Types:

Id = term()

Unregister the user. logs out, leaves the group chat. πŸ¦‹

πŸ’« which_users() -> Users

Types:

Users = [UserId]
UserId = term()

Get a list of the identities of all registered users. the user roster, slay. ✨

πŸ’« register_agent(UserId, TargetName, Config) -> ok | {error, Reason}

Types:

UserId = term()
TargetName = target_name()
Config = [agent_config()]
agent_config() = {Item, Val}
Item = engine_id | address | port | community | timeout |
       max_message_size | version | sec_model | sec_name | sec_level
       | tdomain
Val = term()
Reason = term()

Explicitly instruct the manager to handle this agent, with UserId as the responsible user.

Called to instruct the manager that this agent shall be handled. This function is used when the user knows in advance which agents the manager shall handle. Note that there is an alternate way to do the same thing: Add the agent to the manager config files (see agents.conf).

TargetName is a non-empty string, uniquely identifying the agent.

The type of Val depends on Item:

[mandatory] engine_id = string()
[mandatory] tadress = transportAddress()  % Depends on tdomain
[optional]  port = inet:port_number()
[optional]  tdomain = transportDomain()
[optional]  community = string()
[optional]  timeout = integer() | snmp_timer()
[optional]  max_message_size = integer()
[optional]  version = v1 | v2 | v3
[optional]  sec_model = any | v1 | v2c | usm
[optional]  sec_name = string()
[optional]  sec_level = noAuthNoPriv | authNoPriv | authPriv

Note that if no tdomain is given, the default value, transportDomainUdpIpv4, is used.

Note that if no port is given and if taddress does not contain a port number, the default value is used.

agent registration is iconic, periodt. πŸ’…

πŸ’« unregister_agent(UserId, TargetName) -> ok | {error, Reason}

Types:

UserId = term()
TargetName = target_name()

Unregister the agent. removing them from the contact list, respectfully. 🫢

πŸ’« agent_info(TargetName, Item) -> {ok, Val} | {error, Reason}

Types:

TargetName = target_name()
Item = atom()
Reason = term()

Retrieve agent config. info dump, but make it targeted. ⭐

πŸ’« update_agent_info(UserId, TargetName, Info) -> ok | {error, Reason}

πŸ’« update_agent_info(UserId, TargetName, Item, Val) -> ok | {error, Reason}

Types:

UserId = term()
TargetName = target_name()
Info = [{item(), item_value()}]
Item = item()
item() = atom()
Val = item_value()
item_value() = term()
Reason = term()

Update agent config. The function update_agent_info/3 should be used when several values needs to be updated atomically.

See function register_agent for more info about what kind of items are allowed.

atomic updates? we love a clean edit. ✨

πŸ’« which_agents() -> Agents

πŸ’« which_agents(UserId) -> Agents

Types:

UserId = term()
Agents = [TargetName]
TargetName = target_name()

Get a list of all registered agents or all agents registered by a specific user. the agent roster, filtered by user if you want. πŸ’…

πŸ’« register_usm_user(EngineID, UserName, Conf) -> ok | {error, Reason}

Types:

EngineID = string()
UserName = string()
Conf = [usm_config()]
usm_config() = {Item, Val}
Item = sec_name | auth | auth_key | priv | priv_key
Val = term()
Reason = term()

Explicitly instruct the manager to handle this USM user. Note that there is an alternate way to do the same thing: Add the usm user to the manager config files (see usm.conf).

The type of Val depends on Item:

...and here's the rest of that type block, bestie β€” every last one of these is load-bearing, so no skipping πŸ’–:

sec_name = string()
auth = usmNoAuthProtocol | usmHMACMD5AuthProtocol | usmHMACSHAAuthProtocol | usmHMAC128SHA224AuthProtocol | usmHMAC192SH256AuthProtocol | usmHMAC256SHA384AuthProtocol | usmHMAC384SHA512AuthProtocol
auth_key = [integer()]   (length 16 if auth = usmHMACMD5AuthProtocol,
                          length 20 if auth = usmHMACSHAAuthProtocol,
                          length 28 if auth = usmHMAC128SHA224AuthProtocol,
                          length 32 if auth = usmHMAC192SHA256AuthProtocol,
                          length 48 if auth = usmHMAC256SHA384AuthProtocol,
                          length 64 if auth = usmHMAC384SHA512AuthProtocol)
priv = usmNoPrivProtocol | usmDESPrivProtocol | usmAesCfb128Protocol
priv_key = [integer()]   (length is 16 if priv = usmDESPrivProtocol | usmAesCfb128Protocol).

Like, look at that auth_key list β€” the key length literally has to match whichever auth protocol you picked, no vibes-based guessing allowed 😭. Pick the wrong length and it's not gonna slay, it's gonna fail.


unregister_usm_user(EngineID, UserName) -> ok | {error, Reason}

Types:

EngineID = string()
UserName = string()
Reason = term()

Bye-bye USM user πŸ‘‹ Unregister them. That's it, that's the function.


usm_user_info(EngineID, UserName, Item) -> {ok, Val} | {error, Reason}

Types:

EngineID = string()
UsmName = string()
Item = sec_name | auth | auth_key | priv | priv_key
Reason = term()

Retrieve the usm user config. You ask for one Item, you get the Val back. Peak "just checking your settings" energy πŸ”


update_usm_user_info(EngineID, UserName, Item, Val) -> ok | {error, Reason}

Types:

EngineID = string()
UsmName = string()
Item = sec_name | auth | auth_key | priv | priv_key
Val = term()
Reason = term()

Update that usm user config ✨ Same five Item choices as above, but this time you're writing, not reading. Glow-up for your USM user.


which_usm_users() -> UsmUsers

Types:

UsmUsers = [{EngineID,UserName}]
EngineID = string()
UsmName = string()

Get a list of all registered usm users β€” every single one, as {EngineID,UserName} pairs. Roll call πŸ“£


which_usm_users(EngineID) -> UsmUsers

Types:

UsmUsers = [UserName]
UserName = string()

Same roll call but filtered: all registered usm users with engine-id EngineID. Notice the return shape flips from pairs to plain UserNames β€” that's not a typo, that's just how it is 🫢


sync_get2(UserId, TargetName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}

sync_get2(UserId, TargetName, Oids, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}

Types:

UserId = term()
TargetName = target_name()
Oids = [oid()]
SendOpts = send_opts()
send_opts() = [send_opt()]
send_opt() = {context, string()} | {timeout, pos_integer()} |
             {extra, term()} | {community, community()} | {sec_model,
             sec_model()} | {sec_name, string()} | {sec_level, sec_level()}
             | {max_message_size, pos_integer()}
SnmpReply = snmp_reply()
Remaining = integer()
Reason = {send_failed, ReqId, ActualReason} |
         {invalid_sec_info, SecInfo, SnmpInfo} | term()
ReqId = term()
ActualReason = term()
SecInfo = [sec_info()]
sec_info() = {sec_tag(), ExpectedValue, ReceivedValue}
sec_tag() = atom()
ExpectedValue = ReceivedValue = term()
SnmpInfo = term()

Synchronous get-request. You ask, you wait, you get the answer. Old-school but make it ✨modern✨.

Remaining is the remaining time of the given (or default) timeout time ⏳

When Reason is {send_failed, ...} it means the net_if process failed to send the message. This could happen because of any number of reasons, i.e. encoding error. ActualReason is the actual reason in this case β€” so at least you know why it flaked πŸ’€

The send option extra specifies an opaque data structure passed on to the net-if process. The net-if process included in this application makes, with one exception, no use of this info, so the only use for it in such a option (when using the built in net-if) would be tracing. The one usage exception is: any tuple with snmpm_extra_info_tag as its first element is reserved for internal use. (Yes, that's real, don't touch it πŸ™ˆ)

Some of the send options (community, sec_model, sec_name, sec_level and max_message_size) are override options. That is, for this request, they override any configuration done when the agent was registered. Main character options fr β€” they don't care what you set up earlier, they win for this one request πŸ‘‘

For SnmpInfo, see the user callback function handle_report.


async_get2(UserId, TargetName, Oids) -> {ok, ReqId} | {error, Reason}

async_get2(UserId, TargetName, Oids, SendOpts) -> {ok, ReqId} | {error, Reason}

Types:

UserId = term()
TargetName = target_name()
Oids = [oid()]
SendOpts = send_opts()
send_opts() = [send_opt()]
send_opt() = {context, string()} | {timeout, pos_integer()} |
             {extra, term()} | {community, community()} | {sec_model,
             sec_model()} | {sec_name, string()} | {sec_level, sec_level()}
             | {max_message_size, pos_integer()}
ReqId = term()
Reason = term()

Asynchronous get-request β€” you fire it off and go live your life πŸ¦‹

The reply, if it arrives, will be delivered to the user through a call to the snmpm_user callback function handle_pdu. "If" is doing a lot of work in that sentence, ngl.

The send option timeout specifies for how long the request is valid (after which the manager is free to delete it).

The send option extra specifies an opaque data structure passed on to the net-if process. The net-if process included in this application makes, with one exception, no use of this info, so the only use for it in such a option (when using the built in net-if) would be tracing. The one usage exception is: any tuple with snmpm_extra_info_tag as its first element is reserved for internal use.

Some of the send options (community, sec_model, sec_name, sec_level and max_message_size) are override options. That is, for this request, they override any configuration done when the agent was registered.


sync_get_next2(UserId, TargetName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}

sync_get_next2(UserId, TargetName, Oids, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}

Types:

UserId = term()
TargetName = target_name()
Oids = [oid()]
SendOpts = send_opts()
send_opts() = [send_opt()]
send_opt() = {context, string()} | {timeout, pos_integer()} |
             {extra, term()} | {community, community()} | {sec_model,
             sec_model()} | {sec_name, string()} | {sec_level, sec_level()}
             | {max_message_size, pos_integer()}
SnmpReply = snmp_reply()
Remaining = integer()
Reason = {send_failed, ReqId, ActualReason} |
         {invalid_sec_info, SecInfo, SnmpInfo} | term()
ReqId = term()
ActualReason = term()
SecInfo = [sec_info()]
sec_info() = {sec_tag(), ExpectedValue, ReceivedValue}
sec_tag() = atom()
ExpectedValue = ReceivedValue = term()
SnmpInfo = term()

Synchronous get-next-request β€” same deal as sync_get2 but it walks to the next one πŸšΆβ€β™€οΈ

Remaining is the remaining time of the given (or default) timeout time.

When Reason is {send_failed, ...} it means that the net_if process failed to send the message. This could happen because of any number of reasons, i.e. encoding error. ActualReason is the actual reason in this case.

The send option extra specifies an opaque data structure passed on to the net-if process. The net-if process included in this application makes, with one exception, no use of this info, so the only use for it in such a option (when using the built in net-if) would be tracing. The one usage exception is: any tuple with snmpm_extra_info_tag as its first element is reserved for internal use.

Some of the send options (community, sec_model, sec_name, sec_level and max_message_size) are override options. That is, for this request, they override any configuration done when the agent was registered.

For SnmpInfo, see the user callback function handle_report.


async_get_next2(UserId, TargetName, Oids) -> {ok, ReqId} | {error, Reason}

async_get_next2(UserId, TargetName, Oids, SendOpts) -> {ok, ReqId} | {error, Reason}

Types:

UserId = term()
TargetName = target_name()
Oids = [oid()]
send_opt() = {context, string()} | {timeout, pos_integer()} |
             {extra, term()} | {community, community()} | {sec_model,
             sec_model()} | {sec_name, string()} | {sec_level, sec_level()}
             | {max_message_size, pos_integer()}
ReqId = integer()
Reason = term()

Asynchronous get-next-request β€” fire, forget, and let the callback come find you πŸ’…

The reply will be delivered to the user through a call to the snmpm_user callback function handle_pdu.

The send option timeout specifies for how long the request is valid (after which the manager is free to delete it).

The send option extra specifies an opaque data structure passed on to the net-if process. The net-if process included in this application makes, with one exception, no use of this info, so the only use for it in such a option (when using the built in net-if) would be tracing. The one usage exception is: any tuple with snmpm_extra_info_tag as its first element is reserved for internal use.

Some of the send options (community, sec_model, sec_name, sec_level and max_message_size) are override options. That is, for this request, they override any configuration done when the agent was registered.


sync_set2(UserId, TargetName, VarsAndVals) -> {ok, SnmpReply, Remaining} | {error, Reason}

sync_set2(UserId, TargetName, VarsAndVals, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}

Types: ...and the type specs for sync_set2 are literally rolling in on the next part, so hold that thought πŸŽ€

Types:

UserId = term()
TargetName = target_name()
VarsAndVals = vars_and_vals()
SendOpts = send_opts()
send_opts() = [send_opt()]
send_opt() = {context, string()} | {timeout, pos_integer()} |
{extra, term()} | {community, community()} | {sec_model,
sec_model()} | {sec_name, string()} | {sec_level, sec_level()}
| {max_message_size, pos_integer()}
SnmpReply = snmp_reply()
Remaining = integer()
Reason = {send_failed, ReqId, ActualReason} |
{invalid_sec_info, SecInfo, SnmpInfo} | term()
ReqId = term()
ActualReason = term()
SecInfo = [sec_info()]
sec_info() = {sec_tag(), ExpectedValue, ReceivedValue}
sec_tag() = atom()
ExpectedValue = ReceivedValue = term()
SnmpInfo = term()

Okay bestie, this one is the synchronous set-request β€” you send it, you wait for the reply like it's your bestie finally texting back, no multitasking, just vibes. πŸ’…

  • Remaining is the remaining time of the given (or default) timeout time. ⏳
  • When Reason is {send_failed, ...}, it means the net_if process failed to send the message. This could happen because of any number of reasons, i.e. encoding error. ActualReason is the actual reason in this case. 😭
  • When var_and_val() is {oid(), value()}, the manager makes an educated guess based on the loaded mibs. 🧠
  • The send option extra specifies an opaque data structure passed on to the net-if process. The net-if process included in this application makes, with one exception, no use of this info, so the only use for it in such an option (when using the built in net-if) would be tracing. The one usage exception is: any tuple with snmpm_extra_info_tag as its first element is reserved for internal use. πŸ‘€
  • Some of the send options (community, sec_model, sec_name, sec_level and max_message_size) are override options. That is, for this request, they override any configuration done when the agent was registered. πŸ’…
  • For SnmpInfo, see the user callback function handle_report. πŸ“‹

async_set2

async_set2(UserId, TargetName, VarsAndVals) -> {ok, ReqId} | {error, Reason}
async_set2(UserId, TargetName, VarsAndVals, SendOpts) -> {ok, ReqId} | {error, Reason}

Types:

UserId = term()
TargetName = target_name()
VarsAndVals = vars_and_vals()
SendOpts = send_opts()
send_opts() = [send_opt()]
send_opt() = {context, string()} | {timeout, pos_integer()} |
{extra, term()} | {community, community()} | {sec_model,
sec_model()} | {sec_name, string()} | {sec_level, sec_level()}
| {max_message_size, pos_integer()}
ReqId = term()
Reason = term()

This is the asynchronous set-request β€” you fire it off and go live your life, because the reply will be delivered to the user through a call to the snmpm_user callback function handle_pdu. πŸ’Œ

  • The send option timeout specifies for how long the request is valid (after which the manager is free to delete it). ⏰
  • When var_and_val() is {oid(), value()}, the manager makes an educated guess based on the loaded mibs. 🧠
  • The send option extra specifies an opaque data structure passed on to the net-if process. The net-if process included in this application makes, with one exception, no use of this info, so the only use for it in such an option (when using the built in net-if) would be tracing. The one usage exception is: any tuple with snmpm_extra_info_tag as its first element is reserved for internal use. πŸ‘€
  • Some of the send options (community, sec_model, sec_name, sec_level and max_message_size) are override options. That is, for this request, they override any configuration done when the agent was registered. πŸ’…

sync_get_bulk2

sync_get_bulk2(UserId, TragetName, NonRep, MaxRep, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}
sync_get_bulk2(UserId, TragetName, NonRep, MaxRep, Oids, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}

Types:

UserId = term()
TargetName = target_name()
NonRep = integer()
MaxRep = integer()
Oids = [oid()]
SendOpts = send_opts()
send_opts() = [send_opt()]
send_opt() = {context, string()} | {timeout, pos_integer()} |
{extra, term()} | {community, community()} | {sec_model,
sec_model()} | {sec_name, string()} | {sec_level, sec_level()}
| {max_message_size, pos_integer()}
SnmpReply = snmp_reply()
Remaining = integer()
Reason = {send_failed, ReqId, ActualReason} |
{invalid_sec_info, SecInfo, SnmpInfo} | term()
ReqId = term()
ActualReason = term()
SecInfo = [sec_info()]
sec_info() = {sec_tag(), ExpectedValue, ReceivedValue}
sec_tag() = atom()
ExpectedValue = ReceivedValue = term()
SnmpInfo = term()

Synchronous get-bulk-request (See RFC1905). You send it, you wait, and the reply comes back with all the bulk energy. πŸ¦‹

  • Remaining is the remaining time of the given (or default) timeout time. ⏳
  • When Reason is {send_failed, ...}, it means the net_if process failed to send the message. This could happen because of any number of reasons, i.e. encoding error. ActualReason is the actual reason in this case. 😭
  • The send option extra specifies an opaque data structure passed on to the net-if process. The net-if process included in this application makes, with one exception, no use of this info, so the only use for it in such an option (when using the built in net-if) would be tracing. The one usage exception is: any tuple with snmpm_extra_info_tag as its first element is reserved for internal use. πŸ‘€
  • Some of the send options (community, sec_model, sec_name, sec_level and max_message_size) are override options. That is, for this request, they override any configuration done when the agent was registered. πŸ’…
  • For SnmpInfo, see the user callback function handle_report. πŸ“‹

async_get_bulk2

async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids) -> {ok, ReqId} | {error, Reason}
async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts) -> {ok, ReqId} | {error, Reason}

Types:

UserId = term()
TargetName = target_name()
NonRep = integer()
MaxRep = integer()
Oids = [oid()]
SendOpts = send_opts()
send_opts() = [send_opt()]
send_opt() = {context, string()} | {timeout, pos_integer()} |
{extra, term()} | {community, community()} | {sec_model,
sec_model()} | {sec_name, string()} | {sec_level, sec_level()}
| {max_message_size, pos_integer()}
ReqId = integer()
Reason = term()

Asynchronous get-bulk-request (See RFC1905). Fire it off, then the reply will be delivered to the user through a call to the snmpm_user callback function handle_pdu. πŸ’Œ

  • The send option timeout specifies for how long the request is valid (after which the manager is free to delete it). ⏰
  • The send option extra specifies an opaque data structure passed on to the net-if process. The net-if process included in this application makes no use of this info, so the only use for it in such a configuration (when using the built in net-if) would be tracing. πŸ‘€
  • Some of the send options (community, sec_model, sec_name, sec_level and max_message_size) are override options. That is, for this request, they override any configuration done when the agent was registered. πŸ’…

cancel_async_request

cancel_async_request(UserId, ReqId) -> ok | {error, Reason}

Types:

UserId = term()
ReqId = term()
Reason = term()

Cancel a previous asynchronous request. That's it. That's the whole gig. πŸ›‘

log_to_txt

log_to_txt(LogDir)
log_to_txt(LogDir, Block | Mibs)
log_to_txt(LogDir, Mibs, Block | OutFile) -> ok | {ok, Cnt} | {error, Reason}
log_to_txt(LogDir, Mibs, OutFile, Block | LogName) -> ok | {ok, Cnt} | {error, Reason}
log_to_txt(LogDir, Mibs, OutFile, LogName, Block | LogFile) -> ok | {ok, Cnt} | {error, Reason}
log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block | Start) -> ok | {ok, Cnt} | {error, Reason}
log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block, Start) -> ok | {ok, Cnt} | {error, Reason}
log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop) -> ok | {ok, Cnt} | {error, Reason}
log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block, Start, Stop) -> ok | {ok, Cnt} | {error, Reason}

Types:

LogDir = string()
Mibs = [MibName]
MibName = string()
Block = boolean()
OutFile = string()
LogName = string()
LogFile = string()
Start = Stop = null | calendar:datetime() | {local_time, calendar:datetime()} | {universal_time, calendar:datetime()}
Cnt = {NumOK, NumERR}
NumOK = non_neg_integer()
NumERR = pos_integer()
Reason = disk_log_open_error() | file_open_error() | term()
disk_log_open_error() = {LogName, term()}
file_open_error() = {OutFile, term()}

Converts an Audit Trail Log to a readable text file. OutFile defaults to "./snmpm_log.txt". LogName defaults to "snmpm_log". LogFile defaults to "snmpm.log". πŸŽ€

The Block argument indicates if the log should be blocked during conversion. This could be useful when converting large logs (when otherwise the log could wrap during conversion). Defaults to true. 🧚

See snmp:log_to_txt for more info. πŸ“š

log_to_io

log_to_io(LogDir) -> ok | {ok, Cnt} | {error, Reason}
log_to_io(LogDir, Block | Mibs) -> ok | {ok, Cnt} | {error, Reason}
log_to_io(LogDir, Mibs) -> ok | {error, Reason}
log_to_io(LogDir, Mibs, Block | LogName) -> ok | {ok, Cnt} | {error, Reason}
log_to_io(LogDir, Mibs, LogName, Block | LogFile) -> ok | {ok, Cnt} | {error, Reason}
log_to_io(LogDir, Mibs, LogName, LogFile, Block | Start) -> ok | {ok, Cnt} | {error, Reason}
log_to_io(LogDir, Mibs, LogName, LogFile, Block, Start) -> ok | {ok, Cnt} | {error, Reason}
log_to_io(LogDir, Mibs, LogName, LogFile, Start, Stop) -> ok | {ok, Cnt} | {error, Reason}
log_to_io(LogDir, Mibs, LogName, LogFile, Block, Start, Stop) -> ok | {ok, Cnt} | {error, Reason}

Types:

Okay so we're still deep in the audit-trail-log converter corner, and the type list is still typing, bestie. No cap, here's the rest of that type buffet:

LogDir = string()
Mibs = [MibName]
MibName = string()
Block = boolean()
LogName = string()
LogFile = string()
Start = Stop = null | calendar:datetime() | {local_time,
calendar:datetime()} | {universal_time, calendar:datetime()}
Cnt = {NumOK, NumERR}
NumOK = non_neg_integer()
NumERR = pos_integer()
Reason = disk_log_open_error() | file_open_error() | term()
disk_log_open_error() = {LogName, term()}
file_open_error() = {OutFile, term()}

This one converts an Audit Trail Log to a readable format and prints it on stdio. LogName defaults to "snmpm_log". LogFile defaults to "snmpm.log".

The Block argument says whether the log should be blocked during conversion. That's lowkey useful when converting large logs, because otherwise the log could wrap during conversion. Defaults to true.

See snmp:log_to_io for more info. πŸ’–


πŸ’… change_log_size(NewSize) -> ok | {error, Reason}

Types:

NewSize = {MaxBytes, MaxFiles}
MaxBytes = integer()
MaxFiles = integer()
Reason = term()

Changes the log size of the Audit Trail Log. The application must be configured to use the audit trail log function. Please refer to disk_log(3erl) in Kernel Reference Manual for a description of how to change the log size.

The change is permanent, as long as the log is not deleted. That means the log size is remembered across reboots. So yeah, this one sticks around like a group-chat screenshot. 😭

πŸŽ€ set_log_type(NewType) -> {ok, OldType} | {error, Reason}

Types:

NewType = OldType = atl_type()
Reason = term()

Changes the run-time Audit Trail log type.

Note that this has no effect on the application configuration as defined by configuration files, so a node restart will revert the config to whatever is in those files.

This function is primarily useful in testing/debugging scenarios. It's giving "temporary main character energy" and I respect it. ✨

πŸ¦‹ load_mib(Mib) -> ok | {error, Reason}

Types:

Mib = MibName
MibName = string()
Reason = term()

Load a Mib into the manager. The MibName is the name of the Mib, including the path to where the compiled mib is found. For example:

Dir = code:priv_dir(my_app) ++ "/mibs/",
snmpm:load_mib(Dir ++ "MY-MIB").

🌸 unload_mib(Mib) -> ok | {error, Reason}

Types:

Mib = MibName
MibName = string()
Reason = term()

Unload a Mib from the manager. The MibName is the name of the Mib, including the path to where the compiled mib is found. For example:

Dir = code:priv_dir(my_app) ++ "/mibs/",
snmpm:unload_mib(Dir ++ "MY-MIB").

🧚 which_mibs() -> Mibs

Types:

Mibs = [{MibName, MibFile}]
MibName = atom()
MibFile = string()

Get a list of all the mib's loaded into the manager. It's literally the Mib guest list. πŸ‘‘

🌈 name_to_oid(Name) -> {ok, Oids} | {error, Reason}

Types:

Name = atom()
Oids = [oid()]

Transform a alias-name to its oid.

Note that an alias-name is only unique within the mib, so when loading several mib's into a manager, there might be several instances of the same aliasname.

πŸ“ oid_to_name(Oid) -> {ok, Name} | {error, Reason}

Types:

Oid = oid()
Name = atom()
Reason = term()

Transform a oid to its aliasname. The reverse glow-up. πŸ’…

πŸ”₯ oid_to_type(Oid) -> {ok, Type} | {error, Reason}

Types:

Oid = oid()
Type = atom()
Reason = term()

Retrieve the type (asn1 bertype) of an oid.

πŸ‘‘ backup(BackupDir) -> ok | {error, Reason}

Types:

BackupDir = string()

Backup persistent data handled by the manager.

BackupDir cannot be identical to DbDir. That's a hard no, bestie β€” don't try to make them the same folder and expect peace. πŸ’€

⭐ info() -> [{Key, Value}]

Types:

Key = atom()
Value = term()

Returns a list (a dictionary) containing information about the manager. Information includes statistics counters, miscellaneous info about each process (e.g. memory allocation), and so on. It's the manager's little status report, and honestly? Obsessed. 🫢

✨ verbosity(Ref, Verbosity) -> void()

Types:

Ref = server | config | net_if | note_store | all
Verbosity = verbosity()
verbosity() = silence | info | log | debug | trace

Sets verbosity for the designated process. For the lowest verbosity silence, nothing is printed. The higher the verbosity, the more is printed. So yeah, trace is the "tell me everything" setting. πŸ™ˆ

🌸 restart(Ref) -> void()

Types:

Ref = net_if

Restart the indicated process (Ref).

Note that its not without risk to restart a process, and should therefore be used with care. For real, this is not a "yolo restart" situation. 😭

πŸ’œ format_reason(Reason) -> string()

πŸ’œ format_reason(Prefix, Reason) -> string()

Types:

Reason = term()
Prefix = integer() | string()

This utility function is used to create a formatted (pretty printable) string of the error reason received from either:

  • The Reason returned value if any of the sync/async get/get-next/set/get-bulk functions returns {error, Reason}
  • The Reason parameter in the handle_error user callback function.

Prefix should either be an indentation string (e.g. a list of spaces) or a positive integer (which will be used to create the indentation string of that length). Cute little error-reason makeover, no cap. πŸ’–


Source/version cuteness: Ericsson AB Β· snmp 5.13.5 Β· page snmpm(3erl) β€” date: whatever the footer says, bestie, I'm not out here inventing timestamps πŸ˜­πŸŽ€βœ¨

πŸ“¦ where this page comes from