# SNMP

> Network equipment that answers SNMP v1, v2c or v3 (UPS units, PDUs, switches, routers, precision air conditioning and room sensors) read through its agent at each tag's poll interval: the SNMP agent card, a tag's OID by number or by standard name, the data types each object reads as, reading and writing, the walk that discovers an agent's objects, and two worked examples.

The **SNMP** driver reads and writes the equipment of a technical room through its SNMP agent: UPS
units, PDUs, switches, routers, precision air conditioning and temperature or humidity sensors. It
completes the [Redfish](driver-redfish) driver, which reads the management controllers of servers:
together they cover the technical room. Each tag reads one object of the agent by its OID, such as
`upsBatteryStatus.0` or `ifHCInOctets.2`, and its values land where every other tag's do: in Logic,
on dashboards, in the runs of a [Process](process) test bench.

The station asks: every tag is read at its poll interval, in SNMPv1, SNMPv2c or SNMPv3, and the
**Poll interval (ms)** of the Device card works as on any driver, each tag able to override it. What
the equipment sends by itself, its traps, is not received; see
[Limits worth knowing](#limits-worth-knowing).

A device of this driver is one agent, reached at its host on UDP port 161. The devices sit under the
driver and may be filed in folders, **Driver → Folder → Device → Tag**, as under any driver without a
serial line or a broker.

## The driver's page {#the-drivers-page}

For Configure connector, the page holds the driver's own Scan scope card, with the agent and the
subtrees Discover walks (see [Discovery](#discovery)). Under it stands the **Devices** table of any
driver (see [The device table](connector-drivers#the-device-table)), grown by **Add device** at the
right of its title; empty, it reads "No devices yet." The driver's bar carries **Discover**, greyed
until the Scan scope card is complete.

## Device {#device}

### Connection {#connection}

| Field | Meaning | Default |
| --- | --- | --- |
| **Host** | The agent's host name or IP address. | empty |
| **Port** | The UDP port the agent answers on, 1 to 65535. An empty box shows 161 in grey and the agent is asked on it. | 161 |

A new device has no host: it reads "Host not entered yet", and nothing is sent until it has one.
The Base URI the header shows is the runtime address, with the version, the SNMPv3 security in
force, the response timeout and the retries:
`snmp://192.168.10.40:161?version=2c&timeoutMs=2000&retries=1`, or
`snmp://192.168.10.2:161?version=3&security=authPriv&auth=sha256&priv=aes128&timeoutMs=2000&retries=1`.
It never carries the community, the user or a password.

### The SNMP agent card {#the-snmp-agent-card}

Under the Connection card, the **SNMP agent** card says how the agent is asked. The fields it draws
follow the version and, in SNMPv3, the security level.

| Field | Shown | Meaning | Default |
| --- | --- | --- | --- |
| **SNMP version** | always | SNMPv1, SNMPv2c or SNMPv3, each with a line under it. SNMPv1: "SNMPv1 has no 64-bit counters, and an object the agent lacks refuses the whole request, which the driver then asks again without it." SNMPv2c: "SNMPv2c reads the 64-bit counters, and an object the agent lacks fails that tag alone. Most equipment answers it." SNMPv3: "SNMPv3 signs in with a user, and signs and encrypts its messages as the security level says." | SNMPv2c |
| **Community** | SNMPv1, SNMPv2c | The community the agent answers to, at most 255 bytes, in a box that hides what is typed; empty, it shows `public` as a hint, never as a value. Under it: "An agent ignores a request with a community it does not accept, so a wrong community looks like an agent that does not answer." | empty |
| **SNMPv3 user** | SNMPv3 | The user the agent holds, at most 32 characters. | empty |
| **Security level** | SNMPv3 | **Signed and encrypted (authPriv)**: "Every message is signed with the authentication password and encrypted with the privacy password." **Signed only (authNoPriv)**: "Every message is signed with the authentication password and travels unencrypted." **Neither signed nor encrypted (noAuthNoPriv)**: "Only the user name is sent: nothing is signed and nothing is encrypted." | **Signed and encrypted (authPriv)** |
| **Authentication protocol** | SNMPv3, signed | MD5, SHA-1, SHA-256, SHA-384 or SHA-512. | SHA-1 |
| **Authentication password** | SNMPv3, signed | The password that signs the messages. | empty |
| **Privacy protocol** | SNMPv3, authPriv | DES, AES-128, AES-192 or AES-256. | AES-128 |
| **Privacy password** | SNMPv3, authPriv | The password that encrypts the messages. | empty |
| **Response timeout (ms)** | always | 100 to 60000: "How long a request waits for the agent's answer before it is sent again." | 2000 |
| **Retries** | always | 0 to 5: "How many times an unanswered request is sent again before the device counts as offline." | 1 |

Under the two passwords: "Each password is the one the agent holds for this user, at least 8 characters long."
The user, the security level and the two protocols are the ones the agent is configured with for
that user, on the equipment's own settings page: the station cannot ask the agent for them. MD5,
SHA-1 and DES are offered because much installed equipment accepts nothing newer.

A credential not entered yet is not a mistake: the device is saved, the driver sends nothing to the
agent until it is there, and a calm line under the card says what is missing, the first of these:

| Missing | The card says |
| --- | --- |
| The community (SNMPv1, SNMPv2c) | "Enter the community the agent answers to. Until then the device sends nothing." |
| The user (SNMPv3) | "Enter the SNMPv3 user. Until then the device sends nothing." |
| The authentication password (authNoPriv, authPriv) | "Enter the authentication password. Until then the device sends nothing." |
| The privacy password (authPriv) | "Enter the privacy password. Until then the device sends nothing." |

A device that has its host and still lacks a credential is not connected, and its last error names
the credential its agent waits for. A value the card cannot take is not saved, and the card says why
in red:

| You enter | The card says |
| --- | --- |
| An authentication password shorter than 8 characters | "The authentication password needs at least 8 characters." |
| A privacy password shorter than 8 characters | "The privacy password needs at least 8 characters." |
| A user longer than 32 characters, or a community longer than 255 bytes | "The user takes at most 32 characters and the community at most 255 bytes." |
| A response timeout outside 100 to 60000, or retries outside 0 to 5 | The box goes back to the value in force and says "Enter a number between 100 and 60000." or "Enter a number between 0 and 5." |

The save holds the same rules as the card, and the feed says so when it refuses one:
"Device 'UPS room 1' has an SNMP setting its driver cannot use. Open it and correct the field its panel marks."
The community and the two passwords are kept as every device credential is (see
[Credentials and certificates](connector-devices#credentials-and-certificates)): protected at rest
for the Windows account that entered them, sealed in the configuration export, and never shown in
the Base URI, the journal or an agent's answer. One entered under another Windows account reads
empty, and the device waits for it as for one never entered.

## Tag addressing {#tag-addressing}

### The OID {#the-oid}

A tag of this driver reads one object of its agent. The tag's Source card holds the **OID** box,
with the hint "An OID in numbers, e.g. 1.3.6.1.2.1.1.3.0, or a standard name with its instance, e.g. sysUpTime.0, ifInOctets.2 or upsBatteryStatus.0"
under it. Every request carries the number, whatever form the tag is written in:

| Written | Read as |
| --- | --- |
| `1.3.6.1.2.1.1.3.0`, `.1.3.6.1.2.1.1.3.0`, `iso.3.6.1.2.1.1.3.0` | That number, which the panel names `sysUpTime.0`. |
| `sysUpTime.0`, `sysUpTime`, `SNMPv2-MIB::sysUpTime.0`, with case ignored | A single value, whose one instance `.0` may be left off. |
| `ifInOctets.2` | A column of a table with the index of its row, here interface 2, which is always written. |
| `enterprises.318.1.1.1.2.2.1.0` | A branch with the numbers under it: an object of the equipment's own MIB, shown by its number. |

Under the box, read only, the OID both ways:

| Readout | What it shows |
| --- | --- |
| **MIB name** | The object's standard name with its instance (`ifInOctets.2`), and under it what the MIB says of the object: its MIB, the kind of value it holds and whether it takes a write, such as `IF-MIB · Counter32 · read only` or `UPS-MIB · Integer32 · takes a write`. "No standard name" for an object the driver does not know by name. |
| **Numeric OID** | The OID in numbers, which is what every request carries. |

An object of no standard name adds the line "An object of the equipment's own MIB: shown by its number, since no MIB file is read."
A tag whose OID the driver cannot read is not saved, and the tag's page says why:

| You enter | The tag's page says |
| --- | --- |
| No OID | "OID is required for this driver." |
| A name the driver does not know | "This name is not one of the standard MIB objects the driver knows. Write the OID in numbers." |
| A column without its row, such as `ifInOctets` | "A table column needs the index of its row, e.g. ifInOctets.1." |
| A single value with an instance other than 0, such as `sysUpTime.1` | "A single value has one instance, .0, which may be left off." |
| A branch alone, such as `enterprises` or `ifTable` | "A branch of the tree names no value. Write the numbers of the object under it." |
| A first number above 2, a second one of 40 or more, more than 128 numbers, or a number above 4294967295 | "An OID starts with 0, 1 or 2 and a number below 40, and has at most 128 numbers of at most 4294967295." |
| Anything else that is no OID | "Write the OID in numbers, e.g. 1.3.6.1.2.1.1.3.0, or a standard name with its instance, e.g. sysUpTime.0." |

The save holds the same rule: "Tag 'Battery status' names no OID the SNMP driver can read. Open it and correct the address the tag panel marks."
The read-only **Source address (wire)** line shows the number the driver receives:
`1.3.6.1.2.1.33.1.2.1.0` for a tag written `upsBatteryStatus.0`.

### The names the driver knows {#the-names-the-driver-knows}

The driver carries one table of the standard MIB objects worth naming, written from the RFCs, so a
name means the same thing on every station. No MIB file is read.

| MIB | What it names |
| --- | --- |
| SNMPv2-MIB (RFC 3418) | The system group: `sysDescr`, `sysObjectID`, `sysUpTime`, `sysContact`, `sysName`, `sysLocation`, `sysServices`. |
| IF-MIB (RFC 2863) | `ifNumber`, the interface table (`ifDescr`, `ifOperStatus`, `ifInOctets`, `ifOutErrors` and the rest) and its extension with the 64-bit counters (`ifName`, `ifHCInOctets`, `ifHCOutOctets`, `ifHighSpeed`, `ifAlias`). |
| UPS-MIB (RFC 1628) | A UPS's identity, battery, input, output, bypass, alarms, test, control and configuration: `upsBatteryStatus`, `upsEstimatedChargeRemaining`, `upsOutputSource`, `upsOutputPercentLoad` and the rest. |
| ENTITY-SENSOR-MIB (RFC 3433) | The sensor table: `entPhySensorType`, `entPhySensorScale`, `entPhySensorValue`, `entPhySensorOperStatus` and the rest. |
| ENTITY-MIB (RFC 6933) | The name, description and class of a physical entity, which label a sensor: `entPhysicalName`, `entPhysicalDescr`, `entPhysicalClass`. |
| HOST-RESOURCES-MIB (RFC 2790) | The system (`hrSystemUptime`, `hrSystemProcesses`), the storage table (`hrStorageUsed`) and the processor table (`hrProcessorLoad`). |

`driver_capabilities` lists every name with its OID; see [Agent tools](#agent-tools).

### Data types and access {#data-types-and-access}

The **Data type** list offers only what the object reads as without loss:

| The object holds | Read most naturally as | Also offered |
| --- | --- | --- |
| Integer32, enumerations and TruthValue included | Int32 | Int64, Float, Double, String |
| Counter32, Gauge32, TimeTicks (hundredths of a second) | UInt32 | Int64, Double, String |
| Counter64 | UInt64 | Double, String |
| DisplayString | String | |
| Bytes, an IP address or an OID | String: the bytes in hexadecimal (`00:1A:2B`), the dotted address, the dotted OID | |
| An object of no standard name | Float | Int32, UInt32, Int64, UInt64, Double, String: the agent's answer decides at the read |

A counter is not offered as a Float, which rounds past 16,777,216, and a Counter64 not as an Int64,
which would refuse a count past its half. Boolean is never offered: SNMP has no boolean, and its
TruthValue (1 true, 2 false) and an equipment's own 0 and 1 would read the same type two opposite
ways, so a state reads as an Int32. When the OID changes, a type the new object does not read as
becomes the one it reads most naturally; and a type it does not read as is refused, naming the ones
it does: "ifHCOutOctets.2 is read as one of: UInt64, Double, String."

A standard object its MIB declares read only (the counters, `sysUpTime`, the statuses) is offered
**Read only** alone, and the Access field says "Read only: the device reports this value, and nothing from outside sets it."
A standard object its MIB declares writable (`sysContact`, `sysName`, `sysLocation`,
`ifAdminStatus`, `ifAlias`, the UPS-MIB's test, control and configuration objects) and an object of
the equipment's own MIB are offered every access: whether the agent takes the write is its own
answer.

## Reading {#reading}

At each tag's poll interval the station sends a GET. What the agent answers decides what the tag
shows (see [The value pipeline](connector-value-pipeline)):

| The agent answers | What the read does |
| --- | --- |
| The value | The value, in the tag's type, before the tag's own stages convert it. Text that holds a number (`23.5`, which some equipment writes) reads as a numeric tag. |
| A value the tag's type cannot hold, such as a negative number in a UInt32 | That tag's failed read, with the reason; the device goes on reading its other tags. |
| noSuchObject or noSuchInstance, or an error on that one object | That tag's failed read, named with the agent's answer; the device goes on reading its other tags. In SNMPv1, where one missing object refuses the whole request, the driver asks again without it. |
| Nothing within the response timeout, after every retry | Silence: the device goes offline and reconnects, and the tag's policy for [a device that did not answer](connector-value-pipeline#the-device-did-not-answer) decides what it shows. The cause names the agent, the wait and the attempts, and recalls that an agent also stays silent for a community or an SNMPv3 user it does not accept. |
| An SNMPv3 report (an unknown user, a wrong password or protocol, a security level the agent does not accept), or the host's answer that no agent listens on the port | A connection failure with that cause, in the journal and the device's last error; the device reconnects. |

A device asks one request at a time. A read asks for the tag's object and, in the same request, for
the device's other tags that hold no fresh answer, up to 32 OIDs; an agent that answers that the
request is too big (tooBig) is sent half as many from then on. An answer brought that way serves
another tag's own read while it is younger than half that tag's poll interval, so forty tags cost
one or two requests per pass. An SNMPv3 agent's engine is learned once per connection, and a request
the agent reports as outside its time window is sent once more on the agent's own figures.

## Writing {#writing}

A tag whose access writes sends a SET through the device's queue. A write goes through the same
funnel as any other driver's: the write box takes the engineering value, and the conversion stages
are reversed before the raw value is sent (see [Connector](connector)). The SET carries the kind of
value the agent last answered the object with; failing that, the one its MIB declares; failing that,
the one a GET answers now; and last the tag's own (an Int32 as an Integer32, a UInt32 as a Gauge32, a
String as an OCTET STRING). A value that kind cannot hold is refused before anything is sent.

| The agent answers | What the write reports |
| --- | --- |
| No error | Done. Every answer the device held is forgotten, so the next read asks again. |
| An error status | "Write refused by the equipment: `<reason>`.", the reason naming the status as RFC 3416 writes it, such as `notWritable (17)`, `wrongType (7)` or `wrongValue (10)`, and `readOnly (4)` in SNMPv1. |
| Nothing within the response timeout, after every retry | "Write not confirmed: the equipment did not answer in time." |

## Discovery {#discovery}

### The Scan scope card {#the-scan-scope-card}

For Configure connector, the driver's page carries its **Scan scope** card, under the line
"Walks one agent's standard subtrees and lists what it finds. An SNMPv3 agent is scanned through its device: pick it as the agent to scan."

| Field | Meaning | Default |
| --- | --- | --- |
| **Agent to scan** | **An address typed here**, or a device of the driver by its name. A device's agent is read with its host, port, version, settings and credentials as they are stored, and an edit of the device still waiting to be saved is saved first. It is the only way an SNMPv3 agent is scanned. | **An address typed here** |
| **Agent address** | A typed agent: its host name or IP address, and its port after a colon when it is not the one below. | empty |
| **Port** | A typed agent: 1 to 65535. | 161 |
| **SNMP version** | A typed agent: SNMPv1 or SNMPv2c. | SNMPv2c |
| **Community** | A typed agent: the community it answers to, in a box that hides what is typed, with `public` as its hint. Under it: "Used for this scan only. A device added from the result keeps it as its community." | empty |
| **Subtrees** | One tick each: **System (SNMPv2-MIB)**, **Interfaces (IF-MIB)**, **UPS (UPS-MIB)**, **Sensors (ENTITY-SENSOR-MIB)** and **Host resources (HOST-RESOURCES-MIB)**. | all but Host resources |
| **Also walk** | "One more subtree, in numbers or under a standard name, e.g. enterprises.318. The equipment's own objects come back as numbers." | empty |

What the scope still lacks is said in red under the card, and Discover stays greyed until it is
complete:

| The scope | The card says |
| --- | --- |
| A typed agent with no address | "Type the address of the SNMP agent to scan." |
| A typed agent whose address is not a host | "'http://192.168.0.30' is not the address of an SNMP agent. Write its host name or IP address, optionally with its port, for example 192.168.0.30 or 192.168.0.30:161." |
| A typed agent with no community, or one longer than 255 bytes | "Type the community the agent answers to, at most 255 bytes." |
| A device that no longer exists | "The SNMP device picked to scan no longer exists. Pick another agent to scan." |
| A device without its host or a credential its agent needs | "Device 'UPS room 1' still lacks its host or a credential its agent needs. Complete its SNMP card first." |
| A subtree to walk that is no OID | "'vendor' is not an OID to walk. Write it in numbers or under a standard name, e.g. enterprises.318." |
| Nothing ticked and nothing named | "Tick at least one subtree, or name one to walk." |

When the device to scan has an edit that cannot be saved, the scan does not start:
"Discovery was not started because the edit of the device to scan could not be saved."

### What the scan offers {#what-the-scan-offers}

Discover first asks the agent its name (`sysName.0`), which also proves the agent answers these
credentials, then walks each subtree ticked and the one named, with GETBULK in SNMPv2c and SNMPv3
and GETNEXT in SNMPv1, until the agent answers outside it. The progress line counts what it read:
"Walking the SNMP agent at 192.168.10.40:161: 120 objects found." A scan lists at most 2000 objects
and walks for at most 60 seconds; when it is cut there, or the agent goes silent in the middle, it
keeps what it found and says so:
"The walk of 192.168.10.40:161 stopped early, with 2000 objects found. A scan lists at most 2000 objects and walks for at most 60 s, and it stops where the agent goes silent."

The scan offers one candidate per agent, named by its sysName (by the device's name or the host when
the agent gives none), with the version, timeout and retries it was read with, and the objects it
found as candidate tags:

| Object found | Tag name | Data type | Access |
| --- | --- | --- | --- |
| A single value the driver knows by name | Its name, without the `.0`: `sysUpTime` | The one the value it answered reads most naturally as | Read and write where its MIB declares it writable, Read only otherwise |
| A column of a table the driver knows by name | Its name and row: `ifInOctets.2` | The same | The same |
| An object of the equipment's own MIB | Its number: `1.3.6.1.4.1.318.1.1.1.2.2.1.0` | The same | Read only |

A value no tag type holds is left out. A device added from a typed scan keeps the community the scan
used, protected like every device credential; a device added from a device's scan carries that
device's credentials. A candidate whose agent a device of the driver already reads (the device
scanned, or another at the same host and port) is marked **Already configured**: its card lists
only the objects no tag of that device reads yet, an OID written by name and by number counting as
the same, and **Add tags**, before **Open**, adds the ticked ones to that device. The rest of the
scan's behaviour is on [Discovery](connector-discovery).

A device's own page does the same without its driver's page: **Discover tags**, on the head of
its Tags card, walks that device's agent with its settings and credentials, over the standard
subtrees and the vendor branch its tags already read (`enterprises.318` for a tag under it), and
offers only the objects it has no tag for yet (see [Discovering a device's tags](connector-discovery#discovering-a-devices-tags)).

## Example: a UPS over SNMPv2c {#example-a-ups-over-snmpv2c}

A UPS with a network card answers SNMPv2c at 192.168.10.40, with a read community set on that card.
Read its battery:

1. On the driver's page, **Add device**; name it `UPS room 1`, enter **Host** 192.168.10.40 and keep
   **Port** 161.
2. On the **SNMP agent** card keep SNMPv2c, type the card's read community in **Community**, and
   keep a **Response timeout (ms)** of 2000 and 1 in **Retries**. The line asking for the community
   goes.
3. **Add tag** `Battery status`, **OID** `upsBatteryStatus.0`, **Data type** Int32. Under the box the
   MIB name reads upsBatteryStatus.0 with `UPS-MIB · Integer32 · read only`, the numeric OID
   1.3.6.1.2.1.33.1.2.1.0, and the access stays Read only. The value is 1 unknown, 2 batteryNormal,
   3 batteryLow or 4 batteryDepleted.
4. **Add tag** `Battery charge`, **OID** `upsEstimatedChargeRemaining.0`, **Data type** Int32,
   **Unit** %.
5. If the UPS reports it, **Add tag** `Minutes remaining`, **OID** `upsEstimatedMinutesRemaining.0`,
   **Data type** Int32, **Unit** min.

The Base URI reads `snmp://192.168.10.40:161?version=2c&timeoutMs=2000&retries=1`. An agent does the
same with the tools:

```
device_upsert name="UPS room 1" driver=Snmp host=192.168.10.40 snmpVersion=V2c snmpCommunity="<the UPS card's read community>"
tag_upsert device="UPS room 1" name="Battery status" address=upsBatteryStatus.0 opcUaType=Int32
tag_upsert device="UPS room 1" name="Battery charge" address=upsEstimatedChargeRemaining.0 opcUaType=Int32 unit=%
tag_upsert device="UPS room 1" name="Minutes remaining" address=upsEstimatedMinutesRemaining.0 opcUaType=Int32 unit=min
```

## Example: a switch's interface counters over SNMPv3 {#example-a-switchs-interface-counters-over-snmpv3}

A managed switch at 192.168.10.2 answers SNMPv3 for the user `scada`, set up on the switch with
SHA-256 authentication and AES-128 privacy. Read the traffic and the state of its port 2:

1. **Add device**; name it `Core switch`, **Host** 192.168.10.2, **Port** 161.
2. On the **SNMP agent** card pick SNMPv3, type `scada` in **SNMPv3 user**, keep
   **Signed and encrypted (authPriv)**, pick SHA-256 in **Authentication protocol** and type its
   password, keep AES-128 in **Privacy protocol** and type its password: each the one the switch
   holds for `scada`, at least 8 characters.
3. **Add tag** `Port 2 in`, **OID** `ifHCInOctets.2`. The data type becomes UInt64, the type a
   64-bit counter reads as, and the list offers UInt64, Double and String alone; **Unit** B.
4. **Add tag** `Port 2 out`, **OID** `ifHCOutOctets.2`, UInt64, **Unit** B.
5. **Add tag** `Port 2 state`, **OID** `ifOperStatus.2`, **Data type** Int32: 1 up, 2 down,
   3 testing, 7 lowerLayerDown.

The `.2` is the switch's interface index, the one `ifName.2` names; a scan of the Interfaces subtree
lists every interface with its index. The Base URI reads
`snmp://192.168.10.2:161?version=3&security=authPriv&auth=sha256&priv=aes128&timeoutMs=2000&retries=1`.
With the tools, an `opcUaType` the object does not read as, such as Int32 on `ifHCOutOctets.2`, is
refused with the types it does read as:

```
device_upsert name="Core switch" driver=Snmp host=192.168.10.2 snmpVersion=V3 username=scada password="<authentication password>" snmpSecurityLevel=AuthPriv snmpAuthProtocol=Sha256 snmpPrivacyProtocol=Aes128 snmpPrivacyPassword="<privacy password>"
tag_upsert device="Core switch" name="Port 2 in" address=ifHCInOctets.2 opcUaType=UInt64 unit=B
tag_upsert device="Core switch" name="Port 2 out" address=ifHCOutOctets.2 opcUaType=UInt64 unit=B
tag_upsert device="Core switch" name="Port 2 state" address=ifOperStatus.2 opcUaType=Int32
```

## Agent tools {#agent-tools}

`driver_capabilities` describes this driver under `snmp`: the versions and the credentials each
takes, the security levels and protocols, the response timeout and the retries, how an OID is
written, the types by kind of value, every name the driver knows with its MIB, OID and whether it is
writable, how reads and writes behave, discovery, and the two examples above.
`device_upsert driver=Snmp` takes `host`, `port` (161 by default), `snmpVersion` (`V1`, `V2c`, the
default, or `V3`), `snmpCommunity` on SNMPv1 and SNMPv2c (`''` clears it), and on SNMPv3 `username`
(the user), `password` (its authentication password, at least 8 characters), `snmpSecurityLevel`
(`AuthPriv`, the default, `AuthNoPriv` or `NoAuthNoPriv`), `snmpAuthProtocol` (`Md5`, `Sha1`, the
default, `Sha256`, `Sha384` or `Sha512`), `snmpPrivacyProtocol` (`Des`, `Aes128`, the default,
`Aes192` or `Aes256`) and `snmpPrivacyPassword`; with `responseTimeoutMs` (100 to 60000, 2000 by
default) and `snmpRetries` (0 to 5, 1 by default). A community on an SNMPv3 device, or an SNMPv3
field on a community device, is refused. A device the tools return carries `snmp`: the version,
`hasCommunity`, the security level and the protocols in force, `hasPrivacyPassword`, the timeout,
the retries and `missingCredential`, the credential it still waits for; no secret is ever returned.
`tag_upsert` takes the OID as `address` and `opcUaType`, which defaults to the type the object reads
most naturally as; `wireQuantity` and `eipPath` are refused. `device_discover driver=Snmp` walks
either `target` (a host, with `port` when it is not 161) with `snmpVersion` (`V1` or `V2c`) and
`snmpCommunity`, or `snmpDevice`, the name of a device of the driver, which is the only way to scan
an SNMPv3 agent; `snmpSubtrees` picks the standard subtrees (`System`, `Interfaces`, `Ups`,
`Sensors`, `HostResources`, comma-separated) and `snmpSubtree` adds one more. A scanned community is
not kept by the tools: a device created from what the scan found takes it again in `device_upsert`,
and the tags a configured device lacks are added with `tag_upsert`. The other tools are on
[Agent tools](agent-tools).

## Limits worth knowing {#limits-worth-knowing}

- Traps and informs, what the equipment sends by itself when something happens, are not received:
  every value is read at its poll interval, so a battery that goes low is seen at the next read of
  its status.
- No MIB file is imported. The names the driver knows are those of the standard MIBs it carries; an
  object of the equipment's own MIB, under `enterprises`, is written and shown by its number, and
  what it means is read in the maker's documentation.
- The station is not an SNMP agent: nothing reads the station itself over SNMP.
- A scan reaches an SNMPv3 agent only through a device that holds its user and passwords, and it
  tries no community or user by itself.
- A scan lists at most 2000 objects and walks for at most 60 seconds: on a large switch, untick the
  subtrees that are not needed, or name the one that is.
- No tag is a Boolean: a TruthValue or an equipment's own on and off reads as an Int32.
